<template>
  <div>
    <div class="login-container">
      <!-- 动态背景效果 -->
      <div class="animated-background">
        <canvas ref="backgroundCanvas" class="background-canvas"></canvas>
        <div class="floating-shapes">
          <div v-for="n in 10" :key="n" class="shape" :class="`shape-${n}`"></div>
        </div>
        <div class="gradient-overlay"></div>
      </div>

      <!-- 登录表单 -->
      <div class="login-body">
        <el-tooltip class="item" effect="dark" content="回到首页" placement="top">
          <button class="back-btn" @click="backToHome">
            <i class="el-icon-back"></i>
          </button>
        </el-tooltip>
        <el-tooltip class="item" effect="dark" :content="currentForm === 'login' ? '账号密码登录' : '扫码登录'" placement="top">
          <button class="switch-form-btn" @click="handleSwitchForm">
            <i :class="currentForm === 'login' ? 'el-icon-user' : 'fas fa-qrcode'
              "></i>
          </button>
        </el-tooltip>
        <!-- 微信扫码登录 -->
        <div v-show="currentForm === 'login'" class="form-container">
          <div class="qrcode-content">
            <div class="qrcode-box">
              <!-- 添加扫描线动画 -->
              <div class="scan-line"></div>
              <!-- 添加扫描框 -->
              <div class="scan-border"></div>
              <!-- 这里放二维码图片 -->
              <img v-lazy="'https://kingcola-blog.oss-cn-hangzhou.aliyuncs.com/qrcode_kingcola.jpg'"
                :key="'https://kingcola-blog.oss-cn-hangzhou.aliyuncs.com/qrcode_kingcola.jpg'" alt="微信二维码" />
              <div class="corner-decoration">
                <!-- 四个角的装饰元素 -->
                <span class="corner top-left"></span>
                <span class="corner top-right"></span>
                <span class="corner bottom-left"></span>
                <span class="corner bottom-right"></span>
              </div>
              <!-- 中心装饰 -->
              <div class="center-logo-glow"></div>
            </div>
            <div class="qrcode-info">
              <p class="qrcode-tip">
                登录验证码：
                <span class="code-text">{{ wechatForm.code }}</span>
                <span class="code-text" v-if="wechatForm.code === '验证码已失效'">
                  <i class="fas fa-sync-alt" @click="getWechatLoginCode"></i>
                </span>
              </p>
              <p class="qrcode-tip">微信扫码关注公众号，并发送验证码</p>
            </div>

          </div>

          <div class="divider">
            <el-divider>其他登录方式</el-divider>
          </div>

          <div class="third-party-login">
            <div v-for="(item, type) in loginTypes" :key="type" class="login-icon-wrapper"
              @click="handleThirdPartyLogin(type)" v-if="type !== 'wechat'">
              <el-tooltip :content="item.title" placement="top">
                <div :class="['login-icon', type]">
                  <i :class="item.icon"></i>
                </div>
              </el-tooltip>
            </div>
          </div>
        </div>

        <!-- 账号密码登录表单 -->
        <div v-show="currentForm === 'account'" class="form-container">
          <div class="form-header">
            <h2 class="form-title login-title">账号密码登录</h2>
            <p class="form-subtitle">欢迎回来，请输入您的账号密码</p>
          </div>

          <el-form :model="loginForm" :rules="rules" ref="ruleFrom">
            <el-form-item class="form-item" prop="username">
              <el-input prefix-icon="el-icon-user-solid" v-model="loginForm.username" placeholder="请输入用户名/昵称/邮箱"
                @keyup.enter.native="handleLogin" size="large" />
            </el-form-item>

            <el-form-item class="form-item" prop="password">
              <el-input prefix-icon="el-icon-lock" v-model="loginForm.password" placeholder="请输入密码"
                @keyup.enter.native="handleLogin" show-password size="large" />
            </el-form-item>

            <div class="form-options">
              <el-checkbox v-model="rememberMe">记住我</el-checkbox>
            </div>

            <el-form-item class="form-item">
              <el-button class="submit-btn ripple" :loading="loading" @click="handleLogin" type="primary">
                登 录
              </el-button>
            </el-form-item>
          </el-form>

          <div class="form-switch">
            没有账号？<a @click="switchForm('register')">立即注册</a>
            <span class="divider-line">|</span>
            <a @click="switchForm('forgot')">忘记密码?</a>
          </div>
        </div>

        <!-- 注册表单 -->
        <div v-show="currentForm === 'register'" class="form-container">
          <div class="form-header">
            <h2 class="form-title register-title">注册账号</h2>
            <p class="form-subtitle">欢迎注册，请输入您的账号</p>
          </div>
          <el-form :model="registerForm" :rules="rules" ref="registerForm">
            <el-form-item class="form-item" prop="nickname">
              <el-input prefix-icon="el-icon-user-solid" v-model="registerForm.nickname" placeholder="请输入昵称" />
            </el-form-item>

            <el-form-item class="form-item" prop="email">
              <el-input prefix-icon="el-icon-message" v-model="registerForm.email" placeholder="请输入邮箱" />
            </el-form-item>

            <div class="code-input-group">
              <el-form-item class="form-item code-input" prop="code">
                <el-input prefix-icon="el-icon-key" v-model="registerForm.code" placeholder="请输入验证码" />
              </el-form-item>

              <el-button class="verify-code-btn" type="primary" @click="sendRegisterCode" :disabled="codeSending"
                :loading="codeSending">
                <i class="el-icon-message" v-if="!codeSending && codeButtonText === '发送验证码'"></i>
                {{ codeButtonText }}
              </el-button>
            </div>

            <el-form-item class="form-item" prop="password">
              <el-input prefix-icon="el-icon-lock" v-model="registerForm.password" placeholder="请输入密码" show-password />
            </el-form-item>

            <el-form-item class="form-item" prop="confirmPassword">
              <el-input prefix-icon="el-icon-check" v-model="registerForm.confirmPassword" placeholder="请确认密码"
                show-password />
            </el-form-item>

            <el-form-item class="form-item">
              <el-button class="submit-btn" :loading="loading" @click="handleRegister">
                注 册
              </el-button>
            </el-form-item>

            <div class="form-switch">
              已有账号？<a @click="switchForm('account')">立即登录</a>
            </div>
          </el-form>
        </div>

        <!-- 忘记密码表单 -->
        <div v-show="currentForm === 'forgot'" class="form-container">
          <div class="form-header">
            <h2 class="form-title forgot-title">找回账号</h2>
            <p class="form-subtitle">重置密码，请输入您的邮箱</p>
          </div>
          <el-form :model="forgotForm" :rules="rules" ref="forgotForm">
            <el-form-item class="form-item" prop="email">
              <el-input prefix-icon="el-icon-message" v-model="forgotForm.email" placeholder="请输入注册邮箱" />
            </el-form-item>

            <div class="code-input-group">
              <el-form-item class="form-item code-input" prop="code">
                <el-input prefix-icon="el-icon-key" v-model="forgotForm.code" placeholder="请输入验证码" />
              </el-form-item>

              <el-button class="verify-code-btn" type="primary" @click="sendVerificationCode" :disabled="codeSending"
                :loading="codeSending">
                <i class="el-icon-message" v-if="!codeSending && codeButtonText === '发送验证码'"></i>
                {{ codeButtonText }}
              </el-button>
            </div>

            <el-form-item class="form-item" prop="password">
              <el-input prefix-icon="el-icon-lock" v-model="forgotForm.password" placeholder="请输入新密码" show-password />
            </el-form-item>

            <el-form-item class="form-item" prop="confirmPassword">
              <el-input prefix-icon="el-icon-check" v-model="forgotForm.confirmPassword" placeholder="请确认新密码"
                show-password />
            </el-form-item>

            <el-form-item class="form-item">
              <el-button class="submit-btn" :loading="loading" @click="handleResetPassword">
                重置密码
              </el-button>
            </el-form-item>

            <div class="form-switch">
              <a @click="switchForm('account')">返回登录</a>
            </div>
          </el-form>
        </div>
      </div>
    </div>

    <!-- 滑块验证 -->
    <el-dialog title="请拖动滑块完成拼图" width="360px" :visible.sync="isShowSliderVerify" :close-on-click-modal="false"
      @close="refresh" append-to-body>
      <slider-verify ref="sliderVerify" @success="onSuccess" @fail="onFail" @again="onAgain"
        @login_error="onLoginError" />
    </el-dialog>

    <!-- MFA验证弹窗 -->
    <el-dialog title="两步验证" :visible.sync="mfaDialogVisible" width="400px" :close-on-click-modal="false" append-to-body
      @closed="mfaForm.code = ''" custom-class="auth-dialog">
      <div class="auth-dialog-content">
        <div class="auth-icon">
          <i class="el-icon-key"></i>
        </div>
        <h3 class="auth-title">两步验证</h3>
        <p class="auth-description">您的账户已开启两步验证保护。请打开您的身份验证器应用（如Google Authenticator、Microsoft
          Authenticator或其他类似应用），输入显示的6位数字验证码。</p>
        <p class="auth-tip"><i class="el-icon-info"></i> 验证码每30秒自动更新一次，请确保输入最新的验证码。</p>

        <OtpInput v-model="mfaForm.code" :hasError="mfaCodeError" :errorMessage="mfaCodeErrorMsg"
          :showExplanation="false" @complete="handleMfaLogin" />
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelMfaDialog">取 消</el-button>
        <el-button type="primary" @click="handleMfaLogin" :loading="mfaLoading">验 证</el-button>
      </div>
    </el-dialog>

    <!-- 新设备验证弹窗 -->
    <el-dialog title="新设备验证" :visible.sync="deviceVerifyDialogVisible" width="400px" :close-on-click-modal="false"
      append-to-body @closed="deviceVerifyForm.code = ''" custom-class="auth-dialog">
      <div class="auth-dialog-content">
        <div class="auth-icon device-icon">
          <i class="el-icon-mobile-phone"></i>
        </div>
        <h3 class="auth-title">新设备验证</h3>
        <p class="auth-description">系统检测到您正在使用新设备或浏览器登录。为了保障您的账户安全，我们已向您的注册邮箱（{{ userInfo.email }}）发送了一封包含6位验证码的邮件。</p>
        <p class="auth-tip"><i class="el-icon-info"></i> 请检查您的收件箱和垃圾邮件文件夹。如果您在3分钟内未收到邮件，请联系客服支持。</p>

        <OtpInput v-model="deviceVerifyForm.code" :hasError="deviceCodeError" :errorMessage="deviceCodeErrorMsg"
          :showExplanation="false" @complete="handleVerifyDevice" />
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelDeviceVerifyDialog">取 消</el-button>
        <el-button type="primary" @click="handleVerifyDevice" :loading="deviceVerifyLoading">确 认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { disableScroll, enableScroll } from "@/utils/scroll";
import {
  sendEmailCodeApi,
  registerApi,
  forgotPasswordApi,
  getWechatLoginCodeApi,
  getWechatIsLoginApi,
  getAuthRenderApi,
  getCaptchaSwitchApi,
  loginApi,
  loginWithMfaApi,
  verifyDeviceApi
} from "@/api/auth";
import { setCookie } from "@/utils/cookie";
import SliderVerify from "./components/SliderVerify.vue";
import OtpInput from "@/components/common/OtpInput.vue"; // 导入OtpInput组件

/*
引入一种高效的计算机图形学算法——四叉树（Quadtree）。
四叉树是一种空间分区数据结构，可以将二维空间递归地分割成四个象限，从而能够极快地查询指定区域内的点。
具体步骤如下：
引入 QuadTree 和 Rectangle 类：在脚本中添加这两个辅助类，它们是实现四叉树算法的基础。
构建四叉树：在每一帧的动画循环中，将使用所有粒子的位置信息动态构建一个四叉树。
高效查询：在连接粒子时，不再遍历所有粒子，而是利用四叉树来快速查询每个粒子周边指定范围内的其他粒子。
通过将算法复杂度从原来的 O(n²) 优化到 O(n log n)，
这也将极大地降低CPU的计算压力，显著提升动画的流畅度和帧率，尤其是在粒子效果较为密集时。这是一个质的飞跃。
*/
class Rectangle {
  constructor(x, y, w, h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
  }

  contains(point) {
    return (
      point.x >= this.x - this.w &&
      point.x < this.x + this.w &&
      point.y >= this.y - this.h &&
      point.y < this.y + this.h
    );
  }

  intersects(range) {
    return !(
      range.x - range.w > this.x + this.w ||
      range.x + range.w < this.x - this.w ||
      range.y - range.h > this.y + this.h ||
      range.y + range.h < this.y - this.h
    );
  }
}

class QuadTree {
  constructor(boundary, capacity) {
    this.boundary = boundary;
    this.capacity = capacity;
    this.points = [];
    this.divided = false;
  }

  subdivide() {
    const {
      x,
      y,
      w,
      h
    } = this.boundary;
    const nw = new Rectangle(x - w / 2, y - h / 2, w / 2, h / 2);
    this.northwest = new QuadTree(nw, this.capacity);
    const ne = new Rectangle(x + w / 2, y - h / 2, w / 2, h / 2);
    this.northeast = new QuadTree(ne, this.capacity);
    const sw = new Rectangle(x - w / 2, y + h / 2, w / 2, h / 2);
    this.southwest = new QuadTree(sw, this.capacity);
    const se = new Rectangle(x + w / 2, y + h / 2, w / 2, h / 2);
    this.southeast = new QuadTree(se, this.capacity);
    this.divided = true;
  }

  insert(point) {
    if (!this.boundary.contains(point)) {
      return false;
    }

    if (this.points.length < this.capacity) {
      this.points.push(point);
      return true;
    }

    if (!this.divided) {
      this.subdivide();
    }

    return (
      this.northeast.insert(point) ||
      this.northwest.insert(point) ||
      this.southeast.insert(point) ||
      this.southwest.insert(point)
    );
  }

  query(range, found) {
    if (!found) {
      found = [];
    }

    if (!this.boundary.intersects(range)) {
      return found;
    }

    for (let i = 0; i < this.points.length; i++) {
      const p = this.points[i];
      if (range.contains(p)) {
        found.push(p);
      }
    }

    if (this.divided) {
      this.northwest.query(range, found);
      this.northeast.query(range, found);
      this.southwest.query(range, found);
      this.southeast.query(range, found);
    }

    return found;
  }

  // 新增：清空四叉树
  clear() {
    this.points = [];

    if (this.divided) {
      this.northwest.clear();
      this.northeast.clear();
      this.southwest.clear();
      this.southeast.clear();
      this.divided = false;
      this.northwest = null;
      this.northeast = null;
      this.southwest = null;
      this.southeast = null;
    }
  }
}

const validatePassword = (rule, value, callback) => {
  if (!value) {
    return callback(new Error('请输入密码'));
  }
  if (value.length < 8) {
    callback(new Error('密码长度不能少于 8 位'));
  } else if (!/[a-z]/.test(value)) {
    callback(new Error('密码必须包含至少一个小写字母'));
  } else if (!/[A-Z]/.test(value)) {
    callback(new Error('密码必须包含至少一个大写字母'));
  } else if (!/[!@#$%^&*(),.?":{}|<>]/.test(value)) {
    callback(new Error('密码必须包含至少一个特殊字符'));
  } else {
    callback();
  }
};

export default {
  name: "Login",
  components: {
    SliderVerify,
    OtpInput, // 注册OtpInput组件
  },
  data() {
    return {
      currentForm: "account",
      loading: false,
      userInfo: {
        email: "" // 存储用户邮箱信息
      },
      wechatForm: {
        code: "",
        showQrcode: false,
      },
      countdown: 0,
      loginForm: {
        username: "",
        password: "",
        source: "PC",
      },
      registerForm: {
        nickname: "",
        email: "",
        password: "",
        confirmPassword: "",
        code: "",
      },
      forgotForm: {
        email: "",
        code: "",
        password: "",
        confirmPassword: "",
      },
      loginTypes: {
        github: {
          title: "GitHub账号登录",
          icon: "fab fa-github",
        },
        qq: {
          title: "QQ账号登录",
          icon: "fab fa-qq",
        },
        wechat: {
          title: "微信扫码登录",
          icon: "fab fa-weixin",
        },
        gitee: {
          title: "码云账号登录",
          icon: "fab fa-git-alt",
        },
        weibo: {
          title: "微博账号登录",
          icon: "fab fa-weibo",
        },
      },
      codeSending: false,
      codeButtonText: "发送验证码",
      codeTimer: null,
      pollingTimer: null,
      isShowSliderVerify: false,
      sliderVerify: null,
      rules: {
        nickname: [
          { required: true, message: "请输入昵称", trigger: "blur" },
          {
            min: 3,
            max: 10,
            message: "长度在 3 到 10 个字符",
            trigger: "blur",
          },
        ],
        username: [
          { required: true, message: "请输入用户名/昵称", trigger: "blur" },
          {
            min: 3,
            max: 50,
            message: "长度在 3 到 50 个字符",
            trigger: "blur",
          },
        ],
        email: [
          { required: true, message: "请输入邮箱", trigger: "blur" },
          { type: "email", message: "请输入正确的邮箱", trigger: "blur" },
        ],
        password: [{
          validator: (rule, value, callback) => {
            // 登录表单只需要校验是否输入密码
            if (this.currentForm === 'account') {
              if (!value) {
                return callback(new Error('请输入密码'));
              }
              return callback();
            }
            // 注册和忘记密码表单需要复杂校验
            if (!value) {
              return callback(new Error('请输入密码'));
            }
            if (value.length < 8) {
              callback(new Error('密码长度不能少于 8 位'));
            } else if (!/[a-z]/.test(value)) {
              callback(new Error('密码必须包含至少一个小写字母'));
            } else if (!/[A-Z]/.test(value)) {
              callback(new Error('密码必须包含至少一个大写字母'));
            } else if (!/[!@#$%^&*(),.?":{}|<>]/.test(value)) {
              callback(new Error('密码必须包含至少一个特殊字符'));
            } else {
              callback();
            }
          },
          trigger: ["blur", "change"]
        }],
        confirmPassword: [
          { required: true, message: "请确认密码", trigger: "blur" },
          {
            validator: (rule, value, callback) => {
              if (value !== this.registerForm.password) {
                callback(new Error("两次输入的密码不一致"));
              } else {
                callback();
              }
            },
            trigger: ["blur", "change"],
          },
        ],
        code: [{ required: true, message: "请输入验证码", trigger: "blur" }],
        confirmPassword: [
          { required: true, message: "请确认密码", trigger: "blur" },
          {
            validator: (rule, value, callback) => {
              if (value !== this.registerForm.password && this.currentForm === 'register') {
                callback(new Error("两次输入的密码不一致"));
              } else if (value !== this.forgotForm.password && this.currentForm === 'forgot') {
                callback(new Error("两次输入的密码不一致"));
              } else {
                callback();
              }
            },
            trigger: ["blur", "change"],
          },
        ],
      },
      rememberMe: false,
      mfaDialogVisible: false,
      mfaForm: {
        preAuthToken: null,
        code: ''
      },
      mfaLoading: false,
      mfaCodeError: false,
      mfaCodeErrorMsg: '',
      deviceVerifyDialogVisible: false,
      deviceVerifyForm: {
        preAuthToken: null,
        code: ''
      },
      deviceVerifyLoading: false,
      deviceCodeError: false,
      deviceCodeErrorMsg: '',
    };
  },

  created() {
    // 动画相关属性，不需要响应式
    this.animationFrameId = null;
    this.particles = [];
    this.particleColors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#8957e5', '#3eaf7c'];
    this.particleGlows = {};
    this.isDarkMode = false;
    this.mousePosition = null;
    this.blobs = [];
    this.glowPoints = [];
    this.digitalRain = [];
    this.circuitNodes = [];
    this.energyPulses = [];
    this.pulseIntervalId = null;
    this.glowCanvas = null;
    this.glowCtx = null;
    this.staticBgCanvas = null;
    this.staticBgCtx = null;
    this.lastStaticRedraw = 0;
    this.frameCount = 0;
    this.lastTimestamp = 0;
    this.fps = 60;
    this.performanceLevel = 2; // 2: 高, 1: 中, 0: 低
    this.defaultDigitalRainSet = '';
    this.specialDigitalRainSets = [];
    this.digitalRainCharSets = {
      numeric: '0123456789',
      alphanumeric: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
      symbols: '!@#$%^&*()_+-=[]{}|;:,./<>?',
      specialSymbols: '★☆✦✧♠♣♥♦⚡✴⚙',
      matrix: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
      tech: '01011010101101010101001010',
      brackets: '()[]{}><',
      codesymbols: '+-*/=><:;',
    };

    // 初始化登录类型
    Object.keys(this.loginTypes).forEach((key) => {
      if (!this.$store.state.webSiteInfo?.loginTypeList?.includes(key)) {
        delete this.loginTypes[key];
      }
    });

    // 预先组合字符集，避免在动画循环中重复计算
    this.defaultDigitalRainSet = this.digitalRainCharSets.codesymbols + this.digitalRainCharSets.numeric;
    this.specialDigitalRainSets = [
      this.digitalRainCharSets.tech,
      this.digitalRainCharSets.matrix,
      this.digitalRainCharSets.brackets,
      this.digitalRainCharSets.specialSymbols
    ];

    // 不要在初始化时获取微信登录码，逻辑需要更改
    // this.getWechatLoginCode();
    this.$nextTick(() => {
      disableScroll();
    });
  },

  mounted() {
    this.initBackgroundAnimation();
    // 检查当前主题
    this.checkCurrentTheme();
    // 监听主题变化，更新背景
    this.$store.watch(
      (state) => state.theme,
      (newTheme) => {
        this.updateBackgroundColors(newTheme);
      }
    );

    // 添加进入动画
    setTimeout(() => {
      const loginBody = document.querySelector('.login-body');
      if (loginBody) {
        loginBody.classList.add('login-body-show');
      }
    }, 200);
  },
  methods: {

    /**
     * 滑块验证成功
     */
    async onSuccess(captcha) {
      this.loginForm.nonceStr = captcha.nonceStr;
      this.loginForm.value = captcha.value;
      this.login();
    },
    async login() {
      this.loading = true;
      loginApi(this.loginForm).then(res => {
        // 如果需要设备验证
        if (res.data.deviceVerificationRequired) {
          this.$message.info("登录成功！检测到是新设备，为了您的账户安全，请输入我们发送到您邮箱的验证码。");
          this.deviceVerifyForm.preAuthToken = res.data.preAuthToken;
          this.userInfo.email = res.data.email || ''; // 保存用户邮箱用于显示
          this.deviceVerifyDialogVisible = true;
          this.deviceCodeError = false;
          this.deviceCodeErrorMsg = '';
          if (this.isShowSliderVerify) {
            this.refresh();
            this.isShowSliderVerify = false;
          }
          return;
        }

        // 如果需要MFA验证 (并且还没有最终token)
        if (res.data.mfaEnabled && !res.data.token) {
          this.$message.info("登录成功！您的账户已开启两步验证，请输入验证码继续。");
          this.mfaForm.preAuthToken = res.data.preAuthToken;
          this.mfaDialogVisible = true;
          this.mfaCodeError = false;
          this.mfaCodeErrorMsg = '';
          if (this.isShowSliderVerify) {
            this.refresh();
            this.isShowSliderVerify = false;
          }
          return;
        }

        // 标准成功
        this.$store.commit("SET_TOKEN", res.data.token);
        this.$store.commit("SET_USER_INFO", res.data);
        if (this.rememberMe) {
          setCookie("rememberMe", JSON.stringify(this.loginForm), 7);
        } else {
          setCookie("rememberMe", "", -1);
        }

        if (this.$refs.sliderVerify) {
          this.$refs.sliderVerify.verifySuccessEvent();
        }
        this.$message.success("登录成功");
        this.handleClose();
      }).catch(error => {
        const errorMsg = (error && error.message) || "登录失败，请重试";
        if (errorMsg.includes("用户不存在") ||
          errorMsg.includes("用户名不正确") ||
          errorMsg.includes("密码错误") ||
          errorMsg.includes("用户名或密码错误") ||
          errorMsg.includes("账号不存在") ||
          errorMsg.includes("账号或密码")) {
          if (this.$refs.sliderVerify) {
            this.$refs.sliderVerify.triggerFail(errorMsg);
          }
        } else {
          this.$message.error(errorMsg);
          if (this.$refs.sliderVerify) {
            this.$refs.sliderVerify.refresh();
          }
        }
      }).finally(() => {
        this.loading = false;
      })
    },
    handleMfaLogin() {
      // 验证码必须填写
      if (!this.mfaForm.code || this.mfaForm.code.length !== 6) {
        this.mfaCodeError = true;
        this.mfaCodeErrorMsg = '请输入6位验证码';
        return;
      }

      this.mfaLoading = true;
      this.mfaCodeError = false;
      this.mfaCodeErrorMsg = '';

      loginWithMfaApi(this.mfaForm).then(res => {
        this.$store.commit("SET_TOKEN", res.data.token);
        this.$store.commit("SET_USER_INFO", res.data);
        if (this.rememberMe) {
          setCookie("rememberMe", JSON.stringify(this.loginForm), 7);
        } else {
          setCookie("rememberMe", "", -1);
        }
        this.$message.success("验证成功，已登录！");
        this.mfaDialogVisible = false;
        this.handleClose();
      }).catch(err => {
        this.mfaCodeError = true;
        this.mfaCodeErrorMsg = err.message || '验证码错误或已失效';
      }).finally(() => {
        this.mfaLoading = false;
      });
    },
    cancelMfaDialog() {
      this.mfaDialogVisible = false;
      this.mfaForm.code = '';
      this.mfaCodeError = false;
      this.mfaCodeErrorMsg = '';
    },
    handleVerifyDevice() {
      // 验证码必须填写
      if (!this.deviceVerifyForm.code || this.deviceVerifyForm.code.length !== 6) {
        this.deviceCodeError = true;
        this.deviceCodeErrorMsg = '请输入6位验证码';
        return;
      }

      this.deviceVerifyLoading = true;
      this.deviceCodeError = false;
      this.deviceCodeErrorMsg = '';

      verifyDeviceApi(this.deviceVerifyForm).then(res => {
        // 如果设备验证后还需要MFA (并且还没有最终token)
        if (res.data.mfaEnabled && !res.data.token) {
          this.deviceVerifyDialogVisible = false;
          this.$message.info("设备验证成功！您的账户还开启了两步验证，请继续完成验证。");
          this.mfaForm.preAuthToken = res.data.preAuthToken;
          this.mfaDialogVisible = true;
          return;
        }

        this.$store.commit("SET_TOKEN", res.data.token);
        this.$store.commit("SET_USER_INFO", res.data);
        if (this.rememberMe) {
          setCookie("rememberMe", JSON.stringify(this.loginForm), 7);
        } else {
          setCookie("rememberMe", "", -1);
        }
        this.$message.success("设备验证成功，已登录！");
        this.deviceVerifyDialogVisible = false;
        this.handleClose();
      }).catch(err => {
        this.deviceCodeError = true;
        this.deviceCodeErrorMsg = err.message || '验证码错误或已失效';
      }).finally(() => {
        this.deviceVerifyLoading = false;
      });
    },
    cancelDeviceVerifyDialog() {
      this.deviceVerifyDialogVisible = false;
      this.deviceVerifyForm.code = '';
      this.deviceCodeError = false;
      this.deviceCodeErrorMsg = '';
    },
    /**
     * 滑块验证失败
     */
    onFail() {
      this.$message.error("验证失败，请重试");
    },
    /**
     * 滑块验证重新开始
     */
    onAgain() {
      this.$message.error("验证失败，请重试");
    },
    /**
     * 处理登录错误（非验证错误）
     */
    onLoginError(errorMsg) {
      // 关闭滑块验证弹窗
      this.isShowSliderVerify = false;

      // 显示具体的错误信息
      this.$message.error(errorMsg || "登录失败，请检查用户名和密码");

      // 重置滑块验证组件
      this.$nextTick(() => {
        if (this.$refs.sliderVerify) {
          this.$refs.sliderVerify.refresh();
        }
      });
    },
    /**
     * 刷新
     */
    refresh() {
      if (this.$refs.sliderVerify) {
        this.$refs.sliderVerify.refresh();
      }
    },
    /**
     * 切换表单
     * @param form
     */
    switchForm(form) {
      this.currentForm = form;
      this.loading = false;
      this.clearTimer();

      // 重置表单数据
      if (form === "register") {
        this.registerForm = {
          nickname: "",
          email: "",
          password: "",
          confirmPassword: "",
          code: "",
        };
        // 重置验证码按钮状态
        this.codeSending = false;
        this.codeButtonText = "发送验证码";
      } else if (form === "forgot") {
        this.forgotForm = {
          email: "",
          code: "",
          password: "",
          confirmPassword: "",
        };
        // 重置验证码按钮状态
        this.codeSending = false;
        this.codeButtonText = "发送验证码";
      } else if (form === "account") {
        this.loginForm = {
          username: "",
          password: "",
          source: "PC",
        };
      }

      // 重置表单验证
      this.$nextTick(() => {
        const formRefs = {
          "account": "ruleFrom",
          "register": "registerForm",
          "forgot": "forgotForm",
        };
        if (formRefs[form] && this.$refs[formRefs[form]]) {
          this.$refs[formRefs[form]].clearValidate();
        }
      });

      // 只有当切换到微信登录时才获取微信登录码
      if (form === "login") {
        this.getWechatLoginCode();
      }
    },
    /**
     * 登录
     */
    async handleLogin() {
      this.$refs["ruleFrom"].validate(async (valid) => {
        if (valid) {
          getCaptchaSwitchApi().then((res) => {
            if (!res.data || res.data.configValue === "Y") {
              this.isShowSliderVerify = true;
            } else {
              this.login();
            }
          });
        } else {
          return false;
        }
      });
    },
    /**
     * 注册
     */
    async handleRegister() {
      this.$refs["registerForm"].validate(async (valid) => {
        if (valid) {
          this.loading = true;
          try {
            await registerApi(this.registerForm);
            this.$message.success("注册成功");

            // 重置注册表单数据
            this.registerForm = {
              nickname: "",
              email: "",
              password: "",
              confirmPassword: "",
              code: "",
            };

            // 清除验证码状态
            this.clearTimer();

            // 切换到登录表单
            this.switchForm("account");
          } catch (error) {
            this.$message.error(error.message || "注册失败，请重试");
          } finally {
            this.loading = false;
          }
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    /**
     * 忘记密码
     */
    async handleResetPassword() {
      this.$refs["forgotForm"].validate(async (valid) => {
        if (valid) {
          // 先验证两次密码是否一致
          if (this.forgotForm.password !== this.forgotForm.confirmPassword) {
            this.$message.error("两次输入的密码不一致，请重新输入");
            return;
          }

          this.loading = true;
          try {
            // 调用重置密码接口
            const resetData = {
              email: this.forgotForm.email,
              code: this.forgotForm.code,
              password: this.forgotForm.password
            };
            await forgotPasswordApi(resetData);
            this.$message.success("密码重置成功");

            // 重置忘记密码表单数据
            this.forgotForm = {
              email: "",
              code: "",
              password: "",
              confirmPassword: "",
            };

            // 清除验证码状态
            this.clearTimer();

            // 切换到登录表单
            this.switchForm("account");
          } catch (error) {
            this.$message.error(error.message || "重置失败，请重试");
          } finally {
            this.loading = false;
          }
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    /**
     * 发送忘记密码邮箱验证码
     */
    async sendVerificationCode() {
      if (this.codeSending) return;

      if (!this.forgotForm.email) {
        this.$message.error("请先输入邮箱");
        return;
      }

      this.codeSending = true;
      this.sendEmailCode(this.forgotForm.email, "forgot");
    },

    /**
     * 发送注册邮箱验证码
     */
    sendRegisterCode() {
      if (this.codeSending) return;

      if (!this.registerForm.email) {
        this.$message.error("请先输入邮箱");
        return;
      }
      this.codeSending = true;
      this.sendEmailCode(this.registerForm.email, "register");
    },

    /**
     * 发送邮箱验证码
     */
    sendEmailCode(email, type = "register") {
      // 清除可能存在的旧计时器
      if (this.codeTimer) {
        clearInterval(this.codeTimer);
        this.codeTimer = null;
      }

      sendEmailCodeApi(email, type)
        .then((res) => {
          this.$message.success("发送成功，请前往邮箱查看验证码");
          // 开始倒计时
          this.countdown = 60;
          this.codeButtonText = `${this.countdown}秒后重试`;

          this.codeTimer = setInterval(() => {
            this.countdown--;
            if (this.countdown <= 0) {
              clearInterval(this.codeTimer);
              this.codeTimer = null;
              this.codeSending = false;
              this.codeButtonText = "发送验证码";
            } else {
              this.codeButtonText = `${this.countdown}秒后重试`;
            }
          }, 1000);
        })
        .catch((err) => {
          this.$message.error(err.message || "发送失败");
          this.codeSending = false;
        });
    },

    /**
     * 第三方登录
     */
    handleThirdPartyLogin(type) {
      if (type === "wechat") {
        this.wechatForm.showQrcode = true;
        this.getWechatLoginCode();
        return;
      }
      getAuthRenderApi(type).then((res) => {
        //将当前地址存到cookie中
        if (!window.location.href.includes("login")) {
          setCookie("redirectUrl", window.location.href);
        }
        window.open(res.data, "_self");
      });
    },
    /**
     * 获取微信登录验证码
     */
    getWechatLoginCode() {
      // 清除可能存在的旧计时器
      if (this.codeTimer) {
        clearInterval(this.codeTimer);
        this.codeTimer = null;
      }

      getWechatLoginCodeApi().then((res) => {
        this.wechatForm.code = res.data;
        this.pollingWechatIsLogin();
        // 开始倒计时
        this.countdown = 60;
        this.codeTimer = setInterval(() => {
          this.countdown--;
          if (this.countdown <= 0) {
            clearInterval(this.codeTimer);
            this.codeTimer = null;
            clearInterval(this.pollingTimer);
            this.pollingTimer = null;
            this.wechatForm.code = "验证码已失效";
          }
        }, 1000);
      });
    },
    /**
     * 定时轮询获取微信登录状态
     */
    pollingWechatIsLogin() {
      this.pollingTimer = setInterval(() => {
        getWechatIsLoginApi(this.wechatForm.code).then((res) => {
          if (res.code === 200) {
            this.$store.commit("SET_TOKEN", res.data.token);
            this.$store.commit("SET_USER_INFO", res.data);
            clearInterval(this.pollingTimer);
            this.$message.success("登录成功");
            this.handleClose();
          }
        });
      }, 1000);
    },

    /**
     * 关闭登录弹窗
     */
    handleClose() {
      this.$router.go(-1);
    },

    /**
     * 清理定时器
     */
    clearTimer() {
      if (this.codeTimer) {
        clearInterval(this.codeTimer);
        this.codeTimer = null;
      }
      if (this.pollingTimer) {
        clearInterval(this.pollingTimer);
        this.pollingTimer = null;
      }
      // 重置验证码按钮状态
      this.codeSending = false;
      this.codeButtonText = "发送验证码";
    },

    handleSwitchForm() {
      if (this.currentForm === "login") {
        this.switchForm("account");
      } else if (this.currentForm === "account") {
        this.switchForm("login");
      } else {
        // this.switchForm("login");
        this.switchForm("account"); // 默认切换到账号密码登录
      }
    },

    /**
     * 回到首页
     */
    backToHome() {
      this.$router.push("/");
    },

    /**
     * 预渲染粒子辉光
     */
    preRenderParticleGlows() {
      const glowSize = 64; // 辉光贴图大小
      this.particleGlows = {};

      this.particleColors.forEach(color => {
        const canvas = document.createElement('canvas');
        canvas.width = glowSize;
        canvas.height = glowSize;
        const ctx = canvas.getContext('2d');

        if (ctx) {
          const gradient = ctx.createRadialGradient(
            glowSize / 2, glowSize / 2, 0,
            glowSize / 2, glowSize / 2, glowSize / 2
          );

          const parsedColor = this.parseColor(color);
          gradient.addColorStop(0, this.rgbToString(parsedColor, 0.4));
          gradient.addColorStop(0.4, this.rgbToString(parsedColor, 0.25));
          gradient.addColorStop(1, 'rgba(0,0,0,0)');

          ctx.fillStyle = gradient;
          ctx.fillRect(0, 0, glowSize, glowSize);

          this.particleGlows[color] = canvas;
        }
      });
    },

    /**
     * 初始化背景动画
     */
    initBackgroundAnimation() {
      const canvas = this.$refs.backgroundCanvas;
      if (!canvas) return;

      const ctx = canvas.getContext('2d', {
        alpha: false,
        willReadFrequently: true
      });
      if (!ctx) return;

      // 创建并缓存辉光效果的离屏Canvas
      this.glowCanvas = document.createElement('canvas');
      this.glowCtx = this.glowCanvas.getContext('2d');

      // 创建静态背景的离屏Canvas
      this.staticBgCanvas = document.createElement('canvas');
      this.staticBgCtx = this.staticBgCanvas.getContext('2d', {
        alpha: false,
      });

      const isDark = document.body.classList.contains('dark-theme');
      this.isDarkMode = isDark;

      // 预渲染粒子辉光以提高性能
      this.preRenderParticleGlows();

      // 设置Canvas大小
      const setCanvasSize = () => {
        if (canvas) {
          // 性能优化：检测设备像素比并适当调整分辨率
          const dpr = Math.min(window.devicePixelRatio || 1, 2); // 限制最大像素比为2
          const displayWidth = window.innerWidth;
          const displayHeight = window.innerHeight;

          // 设置画布尺寸
          canvas.width = displayWidth * dpr;
          canvas.height = displayHeight * dpr;

          // 设置CSS尺寸
          canvas.style.width = displayWidth + 'px';
          canvas.style.height = displayHeight + 'px';

          // 调整绘图上下文缩放
          ctx.scale(dpr, dpr);

          // 同步调整辉光效果的Canvas大小
          if (this.glowCanvas) {
            this.glowCanvas.width = displayWidth * dpr;
            this.glowCanvas.height = displayHeight * dpr;
            const glowCtx = this.glowCanvas.getContext('2d');
            if (glowCtx) {
              glowCtx.scale(dpr, dpr);
            }
          }

          // 同步调整静态背景Canvas大小
          if (this.staticBgCanvas) {
            this.staticBgCanvas.width = displayWidth * dpr;
            this.staticBgCanvas.height = displayHeight * dpr;
            const staticCtx = this.staticBgCanvas.getContext('2d');
            if (staticCtx) {
              staticCtx.scale(dpr, dpr);
            }
          }

          // 存储实际显示尺寸供后续使用
          this.displayWidth = displayWidth;
          this.displayHeight = displayHeight;
        }
      };

      // 初始化调整大小
      setCanvasSize();

      // 监听窗口大小变化 - 性能优化：添加防抖
      let resizeTimeout;
      window.addEventListener('resize', () => {
        if (resizeTimeout) clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(() => {
          setCanvasSize();
          this.createBackgroundElements(); // 窗口大小改变时重新创建元素
        }, 200); // 200ms防抖延迟
      });

      // 添加鼠标移动事件监听 - 性能优化：添加节流
      let lastMoveTime = 0;
      window.addEventListener('mousemove', (e) => {
        const now = performance.now();
        if (now - lastMoveTime > 16) { // 约60fps的更新频率
          this.mousePosition = {
            x: e.clientX,
            y: e.clientY
          };
          lastMoveTime = now;
        }
      });

      // 创建元素
      this.createBackgroundElements();

      // 创建科技感额外元素
      this.createTechElements();

      // 初始化性能监控
      this.lastTimestamp = performance.now();
      this.frameTimeHistory = new Array(30).fill(16.67); // 初始化帧时间历史记录为60fps
      this.frameTimeIndex = 0;

      // 动画函数
      const animate = () => {
        if (ctx && canvas) {
          this.frameCount++;
          const now = performance.now();
          const delta = now - this.lastTimestamp;
          this.lastTimestamp = now;

          // 更新帧时间历史记录
          this.frameTimeHistory[this.frameTimeIndex] = delta;
          this.frameTimeIndex = (this.frameTimeIndex + 1) % this.frameTimeHistory.length;

          // 计算平均帧时间和FPS
          const avgFrameTime = this.frameTimeHistory.reduce((sum, time) => sum + time, 0) / this.frameTimeHistory.length;
          this.fps = 1000 / avgFrameTime;

          // 性能优化：动态调整性能等级，使用平滑过渡
          if (this.frameCount % 30 === 0) { // 降低检查频率
            if (this.fps < 35 && this.performanceLevel > 0) {
              this.performanceLevel--;
              console.log('降低性能等级:', this.performanceLevel);
            } else if (this.fps > 58 && this.performanceLevel < 2) {
              this.performanceLevel++;
              console.log('提高性能等级:', this.performanceLevel);
            }
          }

          // 清除画布
          ctx.clearRect(0, 0, this.displayWidth, this.displayHeight);

          // 性能优化：根据性能等级调整静态背景重绘频率
          const staticRedrawInterval = [100, 60, 40][this.performanceLevel] || 100;
          if (now - this.lastStaticRedraw > staticRedrawInterval) {
            this.lastStaticRedraw = now;
            const staticCtx = this.staticBgCtx;
            const staticCanvas = this.staticBgCanvas;
            if (staticCtx && staticCanvas) {
              staticCtx.fillStyle = this.isDarkMode ? '#0f172a' : '#f8fafc';
              staticCtx.fillRect(0, 0, this.displayWidth, this.displayHeight);

              // 绘制科技网格
              this.drawTechGrid(staticCtx, staticCanvas, now);

              // 绘制现代网格
              this.drawModernGrid(staticCtx, staticCanvas, now);
            }
          }

          // 绘制静态背景
          if (this.staticBgCanvas) {
            ctx.drawImage(this.staticBgCanvas, 0, 0, this.displayWidth, this.displayHeight);
          }

          // 核心效果 (始终开启)
          this.updateAndDrawParticles(ctx, canvas, now);
          // 删除流体斑点提高性能和整体流畅性
          // this.drawFluidBlobs(ctx, canvas, now);
          this.drawEnergyPulses(ctx, canvas);
          this.drawDigitalRain(ctx, canvas, now);

          // 中等效果 (性能良好时开启)
          if (this.performanceLevel >= 1) {
            // 启用优化后的光晕效果
            // this.drawGlowPoints(ctx, canvas, now);
          }

          // 高级效果 (性能优秀时开启)
          if (this.performanceLevel >= 2) {
            // 注释掉以下消耗较大的动态元素
            // this.drawCircuitLines(ctx, canvas, now);
          }
        }

        // 继续下一帧动画，使用requestAnimationFrame的回调时间参数
        this.animationFrameId = requestAnimationFrame(animate);
      };

      // 开始动画
      this.animationFrameId = requestAnimationFrame(animate);
    },

    /**
     * 创建背景元素
     */
    createBackgroundElements() {
      // 创建粒子
      this.createParticles();

      // 创建流体斑点
      this.createFluidBlobs();

      // 创建光晕点
      this.createGlowPoints();
    },

    /**
     * 创建科技感额外元素
     */
    createTechElements() {
      // 创建数字雨元素 - 完全重写
      this.digitalRain = [];
      // 增加列数，使数字雨更密集
      const columnCount = Math.floor(window.innerWidth / 28); // 减小列间距，增加列数

      for (let i = 0; i < columnCount; i++) {
        // 优化列的特性，创建更明显、更协调的数字雨效果
        const columnType = i % 5; // 创建5种不同类型的列，增加多样性
        let speed, opacity, length, charType;

        switch (columnType) {
          case 0: // 快速数字列
            speed = 2.8 + Math.random() * 2; // 更快的速度
            opacity = 0.8 + Math.random() * 0.2; // 更高的不透明度
            length = 10 + Math.floor(Math.random() * 8); // 适中长度
            charType = 'numeric';
            break;
          case 1: // 中速字母数字列
            speed = 2.0 + Math.random() * 1.6;
            opacity = 0.7 + Math.random() * 0.3;
            length = 12 + Math.floor(Math.random() * 10);
            charType = 'alphanumeric';
            break;
          case 2: // 中速符号列
            speed = 1.5 + Math.random() * 1.5;
            opacity = 0.6 + Math.random() * 0.3;
            length = 15 + Math.floor(Math.random() * 12);
            charType = 'symbols';
            break;
          case 3: // 特殊效果列（技术风格）
            speed = 2.5 + Math.random() * 1.8;
            opacity = 0.75 + Math.random() * 0.25;
            length = 10 + Math.floor(Math.random() * 12);
            charType = 'special';
            break;
          case 4: // 矩阵风格列
            speed = 2.2 + Math.random() * 2.2;
            opacity = 0.8 + Math.random() * 0.2;
            length = 14 + Math.floor(Math.random() * 10);
            charType = 'matrix'; // 新增的列类型
            break;
        }

        // 初始位置 - 均匀分布，确保屏幕上一开始就有数字雨
        const yPos = Math.random() * window.innerHeight - window.innerHeight * 0.5;

        // 新增：创建多列雨链，实现多个字符链同时落下的效果
        const chainCount = Math.floor(Math.random() * 4) + 2; // 每列2-5个字符链
        const chains = [];

        for (let j = 0; j < chainCount; j++) {
          // 每个链有自己的垂直偏移
          const chainOffset = j * 25 + Math.random() * 15; // 更均匀的分布链
          // 创建字符链
          chains.push({
            yOffset: chainOffset,
            chars: [],
            length: Math.max(5, Math.floor(length * (0.6 + Math.random() * 0.5))), // 增加链长度
            lastCharChange: 0,
            // 每个链可以有不同的变化频率
            changeFrequency: Math.random() * 0.03 + 0.01 // 增加变化频率
          });
        }

        this.digitalRain.push({
          x: (i * 38) + (Math.random() * 15 - 7.5), // 小范围随机x位置增加自然感
          y: yPos,
          speed: speed,
          chars: [],
          length: length,
          opacity: opacity,
          charType: charType,
          changeFrequency: Math.random() * 0.02 + 0.005, // 字符变化频率
          lastCharChange: 0, // 上次字符变化的时间
          headChangeFrequency: Math.random() * 0.1 + 0.1, // 头部字符变化频率
          lastHeadChange: 0, // 上次头部字符变化的时间
          active: Math.random() > 0.3, // 70%的列初始激活
          activationDelay: Math.floor(Math.random() * 8000), // 未激活列的延迟激活时间
          activationTime: Date.now() + Math.floor(Math.random() * 5000), // 激活时间戳
          // 新增：字符链数组，实现一串字符同时落下
          chains: chains,
          // 新增：控制链的间距
          chainSpacing: Math.random() * 10 + 15,
          // 新增：链的水平偏移量
          chainHorizontalOffsets: new Array(chainCount).fill(0).map(() => (Math.random() * 20 - 10))
        });

        // 为列生成初始字符
        this.generateCharsForColumn(this.digitalRain[i]);

        // 为每个链生成字符
        this.digitalRain[i].chains.forEach(chain => {
          this.generateCharsForChain(chain, this.digitalRain[i].charType);
        });
      }

      // 创建电路线节点
      this.circuitNodes = [];
      const nodeCount = Math.floor((window.innerWidth * window.innerHeight) / 40000);

      for (let i = 0; i < nodeCount; i++) {
        this.circuitNodes.push({
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          connections: [],
          size: Math.random() * 3 + 1,
          pulseSpeed: Math.random() * 0.05 + 0.01,
          pulseTime: 0,
          color: this.particleColors[Math.floor(Math.random() * this.particleColors.length)]
        });
      }

      // 为节点创建连接
      for (let i = 0; i < this.circuitNodes.length; i++) {
        const node = this.circuitNodes[i];
        const connectionsCount = Math.floor(Math.random() * 3) + 1; // 每个节点1-3个连接

        for (let j = 0; j < connectionsCount; j++) {
          // 寻找一个合适距离的节点连接
          let closestNode = null;
          let closestDistance = Infinity;

          for (let k = 0; k < this.circuitNodes.length; k++) {
            if (i === k) continue; // 跳过自己

            const otherNode = this.circuitNodes[k];
            const dx = node.x - otherNode.x;
            const dy = node.y - otherNode.y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            // 只连接适当距离范围内的节点
            if (distance > 50 && distance < 200 && distance < closestDistance) {
              closestDistance = distance;
              closestNode = k;
            }
          }

          if (closestNode !== null) {
            // 创建一个连接
            node.connections.push({
              targetIndex: closestNode,
              pulses: [],
              width: Math.random() * 1 + 0.5, // 线宽度
              dashOffset: 0,
              speed: Math.random() * 0.5 + 0.1 // 脉冲移动速度
            });

            // 为连接创建初始脉冲
            if (Math.random() > 0.7) {
              node.connections[node.connections.length - 1].pulses.push({
                position: 0,
                size: Math.random() * 4 + 2,
                opacity: Math.random() * 0.7 + 0.3
              });
            }
          }
        }
      }

      // 创建能量脉冲
      this.energyPulses = [];
      const pulseCount = 3;

      for (let i = 0; i < pulseCount; i++) {
        this.energyPulses.push({
          x: window.innerWidth / 2,
          y: window.innerHeight / 2,
          radius: 0,
          maxRadius: Math.min(window.innerWidth, window.innerHeight) * (Math.random() * 0.3 + 0.2),
          opacity: 0.8,
          speed: Math.random() * 0.5 + 0.5,
          color: this.particleColors[Math.floor(Math.random() * this.particleColors.length)],
          active: false,
          delay: i * 3000 // 每个脉冲之间的延迟
        });
      }

      // 设置定时器来触发脉冲
      this.pulseIntervalId = setInterval(() => {
        const inactivePulse = this.energyPulses.find(pulse => !pulse.active);
        if (inactivePulse) {
          inactivePulse.active = true;
          inactivePulse.radius = 0;

          // 随机选择新的起点
          if (Math.random() > 0.5) {
            inactivePulse.x = Math.random() * window.innerWidth;
            inactivePulse.y = Math.random() * window.innerHeight;
          }

          // 随机更改颜色
          inactivePulse.color = this.particleColors[Math.floor(Math.random() * this.particleColors.length)];
        }
      }, 2000);
    },

    /**
     * 创建粒子
     */
    createParticles() {
      this.particles = [];
      // 优化：降低粒子密度和最大数量
      const baseDensity = window.innerWidth <= 768 ? 20000 : 12000;
      const particleCount = Math.min(
        Math.max(30, Math.floor(window.innerWidth * window.innerHeight / baseDensity)),
        180 // 降低最大粒子数
      );

      for (let i = 0; i < particleCount; i++) {
        // 随机生成种子用于不同粒子的动画相位差
        const seed = Math.random() * 10000;

        // 为不同粒子设置不同速度等级 - 增加更多层次感
        let speedFactor;
        if (i % 5 === 0) {
          speedFactor = 0.4; // 极慢速粒子
        } else if (i % 5 === 1) {
          speedFactor = 0.7; // 慢速粒子
        } else if (i % 5 === 2) {
          speedFactor = 1.0; // 中速粒子  
        } else if (i % 5 === 3) {
          speedFactor = 1.2; // 快速粒子
        } else {
          speedFactor = 1.5; // 极快速粒子
        }

        // 为粒子设置群组属性，相同群组的粒子会有相似的行为
        const group = Math.floor(i / (particleCount / 4));

        this.particles.push({
          id: i, // 添加唯一ID
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          size: Math.random() * 4.5 + 1.5, // 增大粒子大小
          color: this.particleColors[Math.floor(Math.random() * this.particleColors.length)],
          vx: (Math.random() * 0.7 - 0.35) * speedFactor, // 降低基础速度使运动更平滑
          vy: (Math.random() * 0.7 - 0.35) * speedFactor,
          opacity: Math.random() * 0.6 + 0.4, // 提高基础透明度
          seed: seed,
          connectDistance: Math.random() * 180 + 70, // 增大连接距离，增强网络感
          pulseSpeed: Math.random() * 0.003 + 0.001, // 添加脉冲速度属性
          sizeVariation: Math.random() * 0.7 + 0.3, // 大小变化幅度增加
          targetX: null, // 目标位置X - 用于平滑过渡
          targetY: null, // 目标位置Y - 用于平滑过渡
          transitionSpeed: Math.random() * 0.01 + 0.005, // 位置过渡速度
          forceDirectionChangeCountdown: Math.floor(Math.random() * 100) + 50, // 强制方向变化倒计时
          flowDirection: Math.random() * Math.PI * 2, // 增加流向属性
          flowStrength: Math.random() * 0.04 + 0.01, // 降低流动强度
          flowCycle: Math.random() * 5000 + 3000, // 流动方向变化周期
          group: group, // 粒子分组，相同组的粒子会表现出相似的行为
          lifespan: Math.random() * 100 + 150, // 粒子生命周期
          age: 0, // 粒子当前年龄
          turbulenceTime: 0, // 湍流计时器
          respawn: function (width, height) { // 重生函数
            this.x = Math.random() * width;
            this.y = Math.random() * height;
            this.age = 0;
            this.opacity = Math.random() * 0.6 + 0.4;
            // 轻微变化速度和方向，但保持群组特性
            const angleVariation = Math.random() * 0.5 - 0.25;
            const currentSpeed = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
            const newSpeed = currentSpeed * (Math.random() * 0.4 + 0.8); // 速度变化不超过±20%
            const angle = Math.atan2(this.vy, this.vx) + angleVariation;
            this.vx = Math.cos(angle) * newSpeed;
            this.vy = Math.sin(angle) * newSpeed;
          }
        });
      }

      // 为每个粒子组创建一个流向中心点，增强群集效果
      this.flowCenters = [];
      for (let i = 0; i < 4; i++) { // 创建4个流向中心
        this.flowCenters.push({
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          strength: Math.random() * 0.03 + 0.01,
          radius: Math.random() * 300 + 200,
          speedX: (Math.random() * 0.4 - 0.2) * 0.5,
          speedY: (Math.random() * 0.4 - 0.2) * 0.5,
          cycleTime: Math.random() * 8000 + 5000,
        });
      }
    },

    /**
     * 创建流体斑点
     */
    createFluidBlobs() {
      this.blobs = [];
      const blobCount = [6, 10, 15][this.performanceLevel] || 6; // 优化：减少斑点数量

      for (let i = 0; i < blobCount; i++) {
        // 为每个斑点创建独特的颜色和大小特性
        const blobType = i % 4; // 创建4种不同类型的斑点
        let radius, opacity, flowPattern, pulseSpeed;

        switch (blobType) {
          case 0: // 大型慢速斑点
            radius = Math.random() * 380 + 280;
            opacity = 0.03 + Math.random() * 0.04;
            flowPattern = 0; // Lissajous curves
            pulseSpeed = 0.0003 + Math.random() * 0.0004;
            break;
          case 1: // 中型漂浮斑点
            radius = Math.random() * 280 + 180;
            opacity = 0.04 + Math.random() * 0.05;
            flowPattern = 1; // 螺旋模式
            pulseSpeed = 0.0004 + Math.random() * 0.0006;
            break;
          case 2: // 快速小型波浪斑点
            radius = Math.random() * 200 + 120;
            opacity = 0.05 + Math.random() * 0.06;
            flowPattern = 2; // 波浪模式
            pulseSpeed = 0.0005 + Math.random() * 0.0007;
            break;
          case 3: // 超大型背景斑点
            radius = Math.random() * 450 + 320;
            opacity = 0.02 + Math.random() * 0.03;
            flowPattern = 3; // 自定义缓慢移动
            pulseSpeed = 0.0002 + Math.random() * 0.0003;
            break;
        }

        const blobCanvas = document.createElement('canvas');
        // 优化：预先计算最大半径并设置canvas大小，避免在动画循环中重设
        const maxPulse = 1.15; // 预估的最大脉冲振幅
        const maxRadius = radius * (0.85 + maxPulse * 0.25);
        blobCanvas.width = Math.ceil(maxRadius * 2.2);
        blobCanvas.height = Math.ceil(maxRadius * 2.2);

        this.blobs.push({
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          radius: radius,
          angle: Math.random() * Math.PI * 2,
          speed: 0.0008 + Math.random() * 0.0012, // 降低速度使流动感更自然
          opacity: opacity,
          color: this.particleColors[Math.floor(Math.random() * this.particleColors.length)],
          seed: Math.random() * 1000,
          pulseSpeed: pulseSpeed,
          pulseAmplitude: Math.random() * 0.2 + 0.1,   // 调整脉冲幅度参数
          flowPattern: flowPattern,
          phaseOffset: Math.random() * Math.PI * 2,    // 相位偏移增加随机性
          rotation: Math.random() * Math.PI * 2,       // 斑点旋转角度
          rotationSpeed: (Math.random() * 0.001 - 0.0005), // 旋转速度，可正可负
          distortions: [], // 存储扭曲点
          distortionCount: Math.floor(Math.random() * 4) + 4, // 扭曲点数量
          colorVariation: Math.random() * 30 - 15, // 颜色变异值
          // 预创建Canvas和Context以供复用
          canvas: blobCanvas,
          ctx: blobCanvas.getContext('2d', { willReadFrequently: true }),
        });

        // 为每个斑点创建扭曲点
        const blob = this.blobs[this.blobs.length - 1];
        for (let j = 0; j < blob.distortionCount; j++) {
          blob.distortions.push({
            angle: (j / blob.distortionCount) * Math.PI * 2,
            strength: Math.random() * 0.15 + 0.05,
            speed: Math.random() * 0.002 + 0.001,
            offset: Math.random() * Math.PI * 2
          });
        }
      }
    },

    /**
     * 创建光晕点
     */
    createGlowPoints() {
      this.glowPoints = [];
      const pointCount = [3, 6, 10][this.performanceLevel] || 3; // 优化：减少光晕点数量

      for (let i = 0; i < pointCount; i++) {
        // 创建不同类型的光晕点
        const glowType = i % 3;
        let size, opacity, speed, distance, pulseFreq;

        switch (glowType) {
          case 0: // 大型缓慢光晕
            size = 80 + Math.random() * 140;
            opacity = 0.15 + Math.random() * 0.15;
            speed = 0.1 + Math.random() * 0.15;
            distance = 150 + Math.random() * 180;
            pulseFreq = 1.0 + Math.random() * 0.5;
            break;
          case 1: // 中型适中光晕
            size = 50 + Math.random() * 100;
            opacity = 0.2 + Math.random() * 0.2;
            speed = 0.15 + Math.random() * 0.2;
            distance = 100 + Math.random() * 150;
            pulseFreq = 1.5 + Math.random() * 0.5;
            break;
          case 2: // 小型快速光晕
            size = 30 + Math.random() * 70;
            opacity = 0.25 + Math.random() * 0.25;
            speed = 0.2 + Math.random() * 0.25;
            distance = 80 + Math.random() * 120;
            pulseFreq = 2.0 + Math.random() * 0.5;
            break;
        }

        this.glowPoints.push({
          x: Math.random() * window.innerWidth,
          y: Math.random() * window.innerHeight,
          size: size,
          opacity: opacity,
          // 优化：使用单一颜色以支持预渲染
          color: this.particleColors[Math.floor(Math.random() * this.particleColors.length)],
          speed: speed,
          angle: Math.random() * Math.PI * 2,
          distance: distance,
          pulseFrequency: pulseFreq, // 脉冲频率
          seed: Math.random() * 1000,
          movementType: Math.floor(Math.random() * 3), // 0: 圆形, 1: 八字形, 2: 随机
        });
      }
    },

    /**
     * 绘制科技网格
     */
    drawTechGrid(ctx, canvas, time) {
      if (!ctx || !canvas) return;

      const gridSize = this.isDarkMode ? 100 : 80;
      const t = time * 0.0003;

      // 增强网格线的可见度
      const gridColor = this.isDarkMode
        ? 'rgba(64, 158, 255, 0.07)'
        : 'rgba(64, 158, 255, 0.04)';

      ctx.beginPath();
      ctx.strokeStyle = gridColor;
      ctx.lineWidth = 1;

      // 动态消失点 - 随时间缓慢移动
      const offsetX = Math.sin(t * 0.2) * (canvas.width * 0.1);
      const offsetY = Math.cos(t * 0.15) * (canvas.height * 0.1);

      const vanishingPointX = canvas.width / 2 + offsetX;
      const vanishingPointY = canvas.height / 2 + offsetY;

      // 绘制放射性线条 - 增加线条数量
      const lineCount = [8, 12, 16][this.performanceLevel] || 8;
      const angleStep = (2 * Math.PI) / lineCount;

      for (let i = 0; i < lineCount; i++) {
        // 添加微小时间偏移，让不同线条有不同移动速度
        const timeOffset = i * 0.2;
        const angle = i * angleStep + t * (0.8 + Math.sin(i) * 0.3);
        const maxLength = Math.sqrt(canvas.width * canvas.width + canvas.height * canvas.height);

        // 为每条线添加微小波动
        const waveAmplitude = 5 * Math.sin(t * 2 + i);

        ctx.beginPath();
        ctx.moveTo(vanishingPointX, vanishingPointY);

        // 添加中间控制点使线条略微弯曲
        const midpointDistance = maxLength * 0.5;
        const midX = vanishingPointX + Math.cos(angle) * midpointDistance + Math.sin(angle * 3 + t) * waveAmplitude;
        const midY = vanishingPointY + Math.sin(angle) * midpointDistance + Math.cos(angle * 3 + t) * waveAmplitude;

        const endX = vanishingPointX + Math.cos(angle) * maxLength;
        const endY = vanishingPointY + Math.sin(angle) * maxLength;

        // 使用二次贝塞尔曲线绘制带微小弯曲的线条
        ctx.quadraticCurveTo(midX, midY, endX, endY);

        // 随时间渐变线条不透明度
        const opacity = 0.5 + Math.sin(t * 0.5 + i) * 0.3;
        ctx.strokeStyle = this.isDarkMode
          ? `rgba(64, 158, 255, ${0.05 * opacity})`
          : `rgba(64, 158, 255, ${0.03 * opacity})`;

        ctx.stroke();
      }

      // 绘制同心圆 - 添加扭曲和移动效果
      const circleCount = [4, 5, 7][this.performanceLevel] || 4;
      for (let i = 1; i <= circleCount; i++) {
        const baseRadius = (Math.min(canvas.width, canvas.height) / 2) * (i / circleCount);
        // 呼吸效果 + 不同圆的不同脉动频率
        const pulseFreq = 1 + i * 0.3;
        const breatheFactor = Math.sin(t * pulseFreq) * (8 + i * 2);
        const radius = baseRadius + breatheFactor;

        ctx.beginPath();

        // 绘制微扭曲的圆
        const segments = [30, 45, 60][this.performanceLevel] || 30; // 增加段数使圆更平滑
        const angleStep = (Math.PI * 2) / segments;

        for (let j = 0; j <= segments; j++) {
          const segAngle = j * angleStep;
          // 添加小扭曲
          const distort = Math.sin(segAngle * i + t * i * 0.2) * (2 + i);
          const x = vanishingPointX + Math.cos(segAngle) * (radius + distort);
          const y = vanishingPointY + Math.sin(segAngle) * (radius + distort);

          if (j === 0) {
            ctx.moveTo(x, y);
          } else {
            ctx.lineTo(x, y);
          }
        }

        ctx.closePath();
        // 随时间和圆序号变化透明度
        const opacity = 0.5 + Math.sin(t * 0.7 + i * 0.5) * 0.3;
        ctx.strokeStyle = this.isDarkMode
          ? `rgba(64, 158, 255, ${0.06 * opacity})`
          : `rgba(64, 158, 255, ${0.04 * opacity})`;
        ctx.stroke();
      }
    },

    /**
     * 绘制现代网格
     */
    drawModernGrid(ctx, canvas, time) {
      if (!ctx || !canvas) return;

      const gridSize = this.isDarkMode ? 60 : 50;
      // 增强网格线的可见度
      const gridColor = this.isDarkMode ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.03)';
      const t = time * 0.0005;

      // 基础网格
      ctx.beginPath();
      ctx.strokeStyle = gridColor;
      ctx.lineWidth = 1;

      // 动态流动方向 - 创建动态效果
      const flowDirectionX = Math.sin(t * 0.2) * 0.005;
      const flowDirectionY = Math.cos(t * 0.15) * 0.005;

      // 移动速度随时间变化
      const speedFactor = 0.8 + Math.sin(t * 0.3) * 0.2;

      // 绘制横向波动网格 - 增强波浪效果和动态性
      const step = [15, 10, 5][this.performanceLevel] || 15;
      for (let y = 0; y <= canvas.height; y += gridSize) {
        ctx.beginPath();

        // 为每行添加独特的波动效果
        const rowPhase = y * 0.02;
        const rowAmplitude = 4 + Math.sin(y * 0.01 + t) * 2;

        for (let x = 0; x <= canvas.width; x += step) {
          // 添加多层波动 - 主波+噪波
          const primaryWave = Math.sin(x * 0.01 + t * speedFactor + rowPhase) * rowAmplitude;
          const noiseWave = Math.sin(x * 0.03 + t * 0.7) * 2;

          // 添加水平方向的缓动
          const flowOffset = x * flowDirectionX * 20;

          const waveOffset = primaryWave + noiseWave + flowOffset;
          const yPos = y + waveOffset;

          if (x === 0) {
            ctx.moveTo(x, yPos);
          } else {
            ctx.lineTo(x, yPos);
          }
        }

        // 随位置变化透明度，创造深度感
        const opacity = 0.7 + Math.sin(y * 0.01 + t * 0.5) * 0.3;
        ctx.strokeStyle = this.isDarkMode
          ? `rgba(255,255,255,${0.04 * opacity})`
          : `rgba(0,0,0,${0.03 * opacity})`;

        ctx.stroke();
      }

      // 绘制纵向网格线 - 增强波浪效果
      for (let x = 0; x <= canvas.width; x += gridSize) {
        ctx.beginPath();

        // 为每列添加独特的波动特性
        const colPhase = x * 0.02;
        const colAmplitude = 4 + Math.cos(x * 0.01 + t) * 2;

        for (let y = 0; y <= canvas.height; y += step) {
          // 添加多层波动 - 水平方向
          const primaryWave = Math.sin(y * 0.01 + t * speedFactor + colPhase) * colAmplitude;
          const noiseWave = Math.sin(y * 0.03 + t * 0.6) * 2;

          // 添加垂直方向的缓动
          const flowOffset = y * flowDirectionY * 20;

          const waveOffset = primaryWave + noiseWave + flowOffset;
          const xPos = x + waveOffset;

          if (y === 0) {
            ctx.moveTo(xPos, y);
          } else {
            ctx.lineTo(xPos, y);
          }
        }

        // 随位置变化透明度，创造深度感
        const opacity = 0.7 + Math.sin(x * 0.01 + t * 0.5) * 0.3;
        ctx.strokeStyle = this.isDarkMode ?
          `rgba(255,255,255,${0.04 * opacity})` :
          `rgba(0,0,0,${0.03 * opacity})`;

        ctx.stroke();
      }

      // 添加焦点区域 - 让某个区域的网格更明显
      const focusX = canvas.width / 2 + Math.sin(t * 0.3) * canvas.width * 0.3;
      const focusY = canvas.height / 2 + Math.cos(t * 0.2) * canvas.height * 0.3;
      const focusRadius = Math.min(canvas.width, canvas.height) * 0.2;

      // 绘制额外强调的交叉线
      if (this.performanceLevel > 1 && Math.sin(t) > 0.7) { // 随机出现特效
        ctx.beginPath();
        const emphasisColor = this.isDarkMode
          ? 'rgba(64, 158, 255, 0.1)'
          : 'rgba(64, 158, 255, 0.06)';

        ctx.strokeStyle = emphasisColor;
        ctx.lineWidth = 1;

        // 绘制强调十字线
        const length = focusRadius * 1.5;
        ctx.moveTo(focusX - length, focusY);
        ctx.lineTo(focusX + length, focusY);
        ctx.moveTo(focusX, focusY - length);
        ctx.lineTo(focusX, focusY + length);
        ctx.stroke();
      }
    },

    /**
     * 绘制数字矩阵雨
     */
    drawDigitalRain(ctx, canvas, time) {
      if (!this.digitalRain || !ctx || !canvas) return;

      // 性能优化：缓存常量和计算结果
      const t = time * 0.001;
      const globalIntensity = 0.9 + Math.sin(t * 0.5) * 0.1; // 增强全局强度，降低波动幅度
      const isDarkMode = this.isDarkMode;
      const performanceLevel = this.performanceLevel;

      // 增强效果：设置更明显的字体和对齐方式
      ctx.textAlign = 'center';
      const headFont = `bold 18px "Courier New", monospace`; // 增大头部字体
      const bodyFont = `15px "Courier New", monospace`; // 增大普通字体

      // 计算可见范围，优化性能
      const visibleTop = -50;
      const visibleBottom = canvas.height + 50;

      // 确保绘制足够多的列，使效果更明显
      const columnLimit = Math.min(
        performanceLevel < 1 ? Math.floor(this.digitalRain.length * 0.7) :
          performanceLevel < 2 ? Math.floor(this.digitalRain.length * 0.85) :
            this.digitalRain.length,
        this.digitalRain.length
      );

      // 为每一列添加独特的波动效果
      for (let columnIndex = 0; columnIndex < columnLimit; columnIndex++) {
        const column = this.digitalRain[columnIndex];

        // 性能优化：低性能等级下，跳过部分列的绘制
        if (performanceLevel < 2 && columnIndex % (3 - performanceLevel) !== 0) {
          continue;
        }

        // 激活控制 - 实现列的交错效果
        if (!column.active) {
          if (time > column.activationTime) {
            column.active = true;
          } else {
            continue; // 跳过未激活的列
          }
        }

        // 更新y位置，添加微小随机性
        const speedVariation = Math.sin(t + columnIndex * 0.1) * 0.2;
        column.y += column.speed * (1 + speedVariation);

        // 当列超出屏幕底部时重置
        if (column.y - column.length * 20 > canvas.height) {
          column.y = Math.random() * -200 - 50;
          column.active = Math.random() > 0.2; // 80%的概率保持激活

          if (!column.active) {
            column.activationTime = time + column.activationDelay;
            continue; // 跳过本次绘制
          }

          // 重置时更新列特性
          column.speed = (column.speed * 0.8) + (Math.random() * 1.5);
          column.opacity = Math.min(0.9, column.opacity * 0.9 + Math.random() * 0.3);

          // 重新生成字符
          this.generateCharsForColumn(column);

          // 重置所有链
          column.chains.forEach(chain => {
            this.generateCharsForChain(chain, column.charType);
          });
        }

        // 处理字符变化 - 实现真实的动态变化效果
        // 头部字符频繁变化 - 性能优化：减少条件判断次数
        const headChangeInterval = 1000 / (column.headChangeFrequency * globalIntensity);
        if (time - column.lastHeadChange > headChangeInterval && column.chars.length > 0) {
          column.chars[0].value = this.getRandomCharForType(column.charType);
          column.chars[0].changed = time;
          column.lastHeadChange = time;
        }

        // 其它字符随机变化 - 性能优化：减少随机计算
        const charChangeInterval = 1000 / (column.changeFrequency * globalIntensity);
        if (time - column.lastCharChange > charChangeInterval && column.chars.length > 2) {
          // 每次变化1-3个随机字符
          const changeCount = Math.floor(Math.random() * 3) + 1;
          for (let i = 0; i < changeCount; i++) {
            // 随机选择非头部字符
            const charIndex = Math.floor(Math.random() * (column.chars.length - 1)) + 1;
            column.chars[charIndex].value = this.getRandomCharForType(column.charType);
            column.chars[charIndex].changed = time;
          }
          column.lastCharChange = time;
        }

        // 更新字符链的字符
        column.chains.forEach(chain => {
          if (time - chain.lastCharChange > 1000 / (chain.changeFrequency * globalIntensity) && chain.chars.length > 1) {
            const chainChangeCount = Math.floor(Math.random() * 2) + 1;
            for (let i = 0; i < chainChangeCount; i++) {
              const charIndex = Math.floor(Math.random() * chain.chars.length);
              chain.chars[charIndex].value = this.getRandomCharForType(column.charType);
              chain.chars[charIndex].changed = time;
            }
            chain.lastCharChange = time;
          }
        });

        // 绘制字符
        // 为整列微调水平位置，增加生动感
        const horizontalWave = Math.sin(t + columnIndex) * 2;
        const posX = column.x + horizontalWave;

        // 增强色彩表现：根据列类型设置更鲜明的颜色
        let hue, saturation, lightness;
        switch (column.charType) {
          case 'numeric':
            hue = isDarkMode ? 125 : 160; // 绿色/青绿色
            saturation = isDarkMode ? 85 : 75; // 增加饱和度
            lightness = isDarkMode ? 68 : 60; // 增加亮度
            break;
          case 'alphanumeric':
            hue = isDarkMode ? 190 : 210; // 青色/蓝色
            saturation = isDarkMode ? 80 : 70;
            lightness = isDarkMode ? 75 : 65;
            break;
          case 'symbols':
            hue = isDarkMode ? 285 : 270; // 紫色/紫蓝色
            saturation = isDarkMode ? 75 : 65;
            lightness = isDarkMode ? 70 : 60;
            break;
          case 'special':
            hue = isDarkMode ? 45 : 35; // 黄色/橙色
            saturation = isDarkMode ? 90 : 80;
            lightness = isDarkMode ? 65 : 55;
            break;
          case 'matrix': // 新增经典矩阵绿色
            hue = 120; // 经典矩阵绿色
            saturation = 100;
            lightness = isDarkMode ? 50 : 40;
            break;
          default:
            hue = isDarkMode ? 155 : 200;
            saturation = isDarkMode ? 80 : 70;
            lightness = isDarkMode ? 70 : 60;
        }

        // 为每个字符应用微小的色调变化
        const hueVariation = (columnIndex % 20) * 3;
        const charsLength = column.chars.length;

        // 性能优化：使用for循环代替forEach
        for (let charIndex = 0; charIndex < charsLength; charIndex++) {
          const char = column.chars[charIndex];

          // 计算Y位置
          const y = column.y - charIndex * 20;

          // 性能优化：跳过可视区域外的字符
          if (y < visibleTop || y > visibleBottom) continue;

          // 计算字符大小和透明度
          const charAge = (time - char.changed) / 1000; // 字符年龄(秒)
          const fadeInFactor = Math.min(1, charAge * 5); // 淡入效果

          if (charIndex === 0) {
            // 增强头部字符特效
            // 更明显的脉动效果
            const pulse = 0.85 + Math.sin(t * 10 + columnIndex) * 0.15; // 减小波动，增大基础值
            const finalOpacity = column.opacity * pulse;

            ctx.font = headFont;
            // 增强头部光晕效果
            // 即使在低性能模式下也启用轻微阴影，保证视觉效果
            ctx.shadowColor = `hsla(${hue + hueVariation}, 95%, 80%, ${performanceLevel > 1 ? 0.9 : 0.7})`;
            ctx.shadowBlur = performanceLevel > 1 ? 10 * pulse : 6 * pulse;

            // 头部字符使用更亮的颜色
            ctx.fillStyle = `hsla(${hue + hueVariation}, 95%, 80%, ${finalOpacity * fadeInFactor})`;

            // 为头部字符添加额外的发光描边效果
            if (performanceLevel > 0) {
              ctx.strokeStyle = `hsla(${hue + hueVariation}, 90%, 85%, ${finalOpacity * fadeInFactor * 0.3})`;
              ctx.lineWidth = 0.5;
              ctx.strokeText(char.value, posX, y);
            }
          } else {
            // 增强普通字符渐变效果
            // 计算相对位置，减小衰减率使更多字符可见
            const relativePosition = charIndex / column.length;
            const brightnessGradient = char.brightness * (1 - relativePosition * 0.7); // 从0.8减小到0.7

            // 低性能模式下禁用阴影，高性能模式启用轻微阴影
            ctx.shadowBlur = performanceLevel > 1 ? 3 : 0;
            if (performanceLevel > 1) {
              ctx.shadowColor = `hsla(${hue + hueVariation}, ${saturation}%, ${lightness + 10}%, 0.5)`;
            }
            ctx.font = bodyFont;

            // 普通字符颜色 - 增加透明度和亮度
            const finalOpacity = column.opacity * brightnessGradient * globalIntensity * 0.95; // 从0.9增加到0.95
            ctx.fillStyle = `hsla(${hue + hueVariation}, ${saturation}%, ${lightness * brightnessGradient + 5}%, ${finalOpacity * fadeInFactor})`;
          }

          // 绘制字符
          ctx.fillText(char.value, posX, y);

          // 偶尔为字符添加故障效果 - 性能优化：减少随机计算
          if (charIndex === 0 && performanceLevel > 1 && Math.random() > 0.99) {
            const glitchOffset = (Math.random() - 0.5) * 6;
            ctx.globalAlpha = 0.3;
            ctx.fillText(char.value, posX + glitchOffset, y);
            ctx.globalAlpha = 1.0;
          }
        }

        // 绘制字符链 - 增强效果
        column.chains.forEach((chain, chainIndex) => {
          // 为每个链添加水平偏移与动态波动
          const chainWave = Math.sin(t * 2 + chainIndex * 1.5) * 3; // 添加水平波动
          const chainHorizontalOffset = column.chainHorizontalOffsets[chainIndex] + chainWave;
          const chainX = posX + chainHorizontalOffset;

          // 为每个链应用垂直偏移，并添加动态效果
          const chainSpeed = column.speed * (1 + chainIndex * 0.1); // 不同链有微妙的速度差异
          const chainStartY = column.y - chain.yOffset + (Math.sin(t + chainIndex) * 2); // 添加小幅度垂直波动

          // 为每个链应用更明显的色调变化，增强区分度
          const chainHueVariation = hueVariation + (chainIndex * 8);

          for (let charIndex = 0; charIndex < chain.chars.length; charIndex++) {
            const char = chain.chars[charIndex];

            // 计算Y位置 - 更紧凑的布局
            const y = chainStartY - charIndex * 13; // 链字符间距更紧凑

            // 跳过可视区域外的字符
            if (y < visibleTop || y > visibleBottom) continue;

            // 计算淡入效果
            const charAge = (time - char.changed) / 1000;
            const fadeInFactor = Math.min(1, charAge * 5);

            // 根据字符在链中的位置设置不同的样式
            if (charIndex === 0) {
              // 链头部字符 - 增强头部效果
              const pulse = 0.75 + Math.sin(t * 8 + columnIndex + chainIndex) * 0.25;
              const finalOpacity = column.opacity * pulse; // 提高透明度，使链头与主列一样明显

              ctx.font = `bold 15px "Courier New", monospace`; // 增大链头字符

              // 为链头添加光晕效果
              ctx.shadowColor = `hsla(${hue + chainHueVariation}, 90%, 75%, 0.6)`;
              ctx.shadowBlur = 5 * pulse;

              // 头部字符颜色 - 更明亮
              ctx.fillStyle = `hsla(${hue + chainHueVariation}, 90%, 75%, ${finalOpacity * fadeInFactor})`;
            } else {
              // 链的普通字符 - 优化渐变
              const relativePosition = charIndex / chain.length;
              // 减小衰减率，使链中更多字符可见
              const brightnessGradient = char.brightness * (1 - relativePosition * 0.6);

              ctx.shadowBlur = 0; // 禁用普通字符阴影以提高性能
              ctx.font = `13px "Courier New", monospace`; // 增大链字符尺寸

              // 普通字符颜色 - 更明亮
              const finalOpacity = column.opacity * brightnessGradient * globalIntensity * 0.85;
              ctx.fillStyle = `hsla(${hue + chainHueVariation}, ${saturation}%, ${lightness * brightnessGradient + 5}%, ${finalOpacity * fadeInFactor})`;
            }

            // 绘制字符
            ctx.fillText(char.value, chainX, y);

            // 随机添加字符重影效果，增强科技感
            if (performanceLevel > 1 && Math.random() > 0.97) {
              const glitchOffset = (Math.random() * 2 - 1) * 3;
              ctx.globalAlpha = 0.3;
              ctx.fillText(char.value, chainX + glitchOffset, y);
              ctx.globalAlpha = 1.0;
            }
          }
        });
      }

      // 重置阴影效果，避免影响其他绘制
      ctx.shadowBlur = 0;
    },

    /**
     * 获取特定类型的随机字符
     */
    getRandomCharForType(charType) {
      // 从预缓存的字符集获取可见字符
      const sets = this.digitalRainCharSets;
      switch (charType) {
        case 'numeric':
          return sets.numeric.charAt(Math.floor(Math.random() * sets.numeric.length));
        case 'alphanumeric':
          return sets.alphanumeric.charAt(Math.floor(Math.random() * sets.alphanumeric.length));
        case 'symbols':
          return sets.symbols.charAt(Math.floor(Math.random() * sets.symbols.length));
        case 'matrix': // 新增专门的矩阵风格，主要是大写字母和数字
          return sets.matrix.charAt(Math.floor(Math.random() * sets.matrix.length));
        case 'special':
          // 优化：从预先缓存的数组中随机选择一个字符集，然后随机选择一个字符
          const chosenSet = this.specialDigitalRainSets[Math.floor(Math.random() * this.specialDigitalRainSets.length)];
          return chosenSet.charAt(Math.floor(Math.random() * chosenSet.length));
        default:
          // 优化：使用预先组合好的默认字符集
          return this.defaultDigitalRainSet.charAt(Math.floor(Math.random() * this.defaultDigitalRainSet.length));
      }
    },

    /**
     * 绘制科技电路线
     */
    drawCircuitLines(ctx, canvas, time) {
      if (!this.circuitNodes || !ctx || !canvas) return;

      const t = time * 0.001;

      // 全局效果控制
      const globalPulseEffect = 0.5 + Math.sin(t * 0.2) * 0.3; // 全局脉冲强度因子
      const energyWave = Math.sin(t * 0.5) * 0.2 + 0.8; // 全局能量波动

      // 绘制节点和连接
      this.circuitNodes.forEach((node, index) => {
        // 节点位置动态微调 - 为节点添加微小的振动以增强活力
        const vibrationScale = 0.8; // 控制振动幅度
        const posX = node.x + Math.sin(t * 0.7 + index * 0.2) * vibrationScale;
        const posY = node.y + Math.cos(t * 0.6 + index * 0.3) * vibrationScale;

        // 节点脉动效果增强
        node.pulseTime += node.pulseSpeed * energyWave;
        const basePulseScale = 0.7 + Math.sin(node.pulseTime) * 0.3;
        // 添加微小不规则性，使脉动更自然
        const randomFactor = 0.9 + Math.sin(time * 2 + index * 10) * 0.1;
        const pulseScale = basePulseScale * randomFactor * globalPulseEffect;

        // 绘制节点发光效果
        const nodeGlowRadius = node.size * 2 * pulseScale;
        const glow = ctx.createRadialGradient(
          posX, posY, node.size * 0.5,
          posX, posY, nodeGlowRadius
        );

        // 根据节点索引微调颜色，使不同节点有略微不同的色调
        const nodeColor = node.color;
        const colorShift = index % 3;  // 0, 1, 或 2
        let enhancedColor = nodeColor;

        if (colorShift === 1) {
          enhancedColor = this.adjustColorBrightness(nodeColor, 15);  // 稍微亮一点
        } else if (colorShift === 2) {
          enhancedColor = this.adjustColorBrightness(nodeColor, -15);  // 稍微暗一点
        }

        // 创建发光渐变
        glow.addColorStop(0, this.adjustColorOpacity(enhancedColor, 0.7 * pulseScale));
        glow.addColorStop(0.5, this.adjustColorOpacity(enhancedColor, 0.3 * pulseScale));
        glow.addColorStop(1, this.adjustColorOpacity(enhancedColor, 0));

        // 绘制节点光晕
        ctx.beginPath();
        ctx.fillStyle = glow;
        ctx.arc(posX, posY, nodeGlowRadius, 0, Math.PI * 2);
        ctx.fill();

        // 绘制节点核心
        ctx.beginPath();
        // 使用内部渐变使节点看起来更立体
        const nodeCore = ctx.createRadialGradient(
          posX - node.size * 0.3, posY - node.size * 0.3, node.size * 0.1,
          posX, posY, node.size
        );

        nodeCore.addColorStop(0, this.adjustColorOpacity(this.adjustColorBrightness(enhancedColor, 40), 0.9 * pulseScale));
        nodeCore.addColorStop(0.7, this.adjustColorOpacity(enhancedColor, 0.7 * pulseScale));
        nodeCore.addColorStop(1, this.adjustColorOpacity(this.adjustColorBrightness(enhancedColor, -20), 0.5 * pulseScale));

        ctx.fillStyle = nodeCore;
        ctx.arc(posX, posY, node.size * pulseScale, 0, Math.PI * 2);
        ctx.fill();

        // 添加内部细节环
        if (node.size > 2 && this.performanceLevel > 0) {
          ctx.beginPath();
          ctx.strokeStyle = this.adjustColorOpacity(this.adjustColorBrightness(enhancedColor, 60), 0.6 * pulseScale);
          ctx.lineWidth = 0.8;
          ctx.arc(posX, posY, node.size * 0.6 * pulseScale, 0, Math.PI * 2);
          ctx.stroke();
        }

        // 绘制节点连接 - 增强可见性和动态性
        node.connections.forEach(connection => {
          const targetNode = this.circuitNodes[connection.targetIndex];

          if (targetNode) {
            // 计算目标节点的位置 (同样加上振动)
            const targetPosX = targetNode.x + Math.sin(t * 0.7 + connection.targetIndex * 0.2) * vibrationScale;
            const targetPosY = targetNode.y + Math.cos(t * 0.6 + connection.targetIndex * 0.3) * vibrationScale;

            // 计算连接线的长度和方向
            const dx = targetPosX - posX;
            const dy = targetPosY - posY;
            const distance = Math.sqrt(dx * dx + dy * dy);
            const angle = Math.atan2(dy, dx);

            // 虚线动画增强效果
            // 动态改变虚线参数以产生"流动"感
            const dashAnimSpeed = connection.speed * 1.2 * energyWave;
            connection.dashOffset += dashAnimSpeed;

            // 为不同连接设置不同虚线样式
            const dashStyle = (index + connection.targetIndex) % 3;
            let dashPattern;

            if (dashStyle === 0) {
              dashPattern = [4, 4]; // 均匀虚线
            } else if (dashStyle === 1) {
              dashPattern = [2, 4, 6, 4]; // 变化式虚线
            } else {
              dashPattern = [1, 3, 8, 3]; // 更长间隔虚线
            }

            // 绘制线条 - 带渐变效果
            ctx.strokeStyle = this.adjustColorOpacity(enhancedColor, 0.5 * globalPulseEffect);

            ctx.beginPath();
            ctx.lineWidth = connection.width * (0.8 + globalPulseEffect * 0.4);

            // 应用虚线样式
            ctx.setLineDash(dashPattern);
            ctx.lineDashOffset = connection.dashOffset;

            // 绘制连接线 - 用贝塞尔曲线增加一点弯曲
            const curveFactor = Math.sin(t * 0.3 + index + connection.targetIndex) * 0.1;
            const midX = (posX + targetPosX) / 2 - dy * curveFactor;
            const midY = (posY + targetPosY) / 2 + dx * curveFactor;

            ctx.beginPath();
            ctx.moveTo(posX, posY);
            ctx.quadraticCurveTo(midX, midY, targetPosX, targetPosY);
            ctx.stroke();

            // 重置虚线样式
            ctx.setLineDash([]);

            // 脉冲更新与增强
            connection.pulses.forEach((pulse, pulseIndex) => {
              // 更新脉冲位置 - 速度随全局能量波动变化
              pulse.position += connection.speed * 1.5 * energyWave;

              // 使用贝塞尔曲线插值得到脉冲位置
              const t = pulse.position / distance;
              // 超出终点时删除或重置
              if (t >= 1) {
                if (Math.random() > 0.3) {
                  // 重置脉冲到起点
                  pulse.position = 0;
                } else {
                  // 移除这个脉冲
                  connection.pulses.splice(pulseIndex, 1);
                }
                return; // 提前结束此脉冲处理
              }

              // 使用二次贝塞尔曲线计算脉冲实际位置
              const pulseX = (1 - t) * (1 - t) * posX + 2 * (1 - t) * t * midX + t * t * targetPosX;
              const pulseY = (1 - t) * (1 - t) * posY + 2 * (1 - t) * t * midY + t * t * targetPosY;

              // 脉冲大小变化效果
              const pulseScaleFactor = 1 + Math.sin(time * 3 + pulseIndex) * 0.3;
              const currentSize = pulse.size * pulseScaleFactor * globalPulseEffect;

              // 绘制脉冲发光效果
              const pulseGlow = ctx.createRadialGradient(
                pulseX, pulseY, currentSize * 0.2,
                pulseX, pulseY, currentSize * 2
              );

              pulseGlow.addColorStop(0, this.adjustColorOpacity(this.adjustColorBrightness(enhancedColor, 40), pulse.opacity * globalPulseEffect));
              pulseGlow.addColorStop(0.6, this.adjustColorOpacity(enhancedColor, pulse.opacity * 0.5 * globalPulseEffect));
              pulseGlow.addColorStop(1, 'rgba(0, 0, 0, 0)');

              ctx.beginPath();
              ctx.fillStyle = pulseGlow;
              ctx.arc(pulseX, pulseY, currentSize * 2, 0, Math.PI * 2);
              ctx.fill();

              // 绘制脉冲核心
              ctx.beginPath();
              ctx.fillStyle = this.adjustColorOpacity(this.adjustColorBrightness(enhancedColor, 60), pulse.opacity * globalPulseEffect);
              ctx.arc(pulseX, pulseY, currentSize, 0, Math.PI * 2);
              ctx.fill();

              // 动态脉冲尾巴效果
              if (t > 0.05 && this.performanceLevel > 0) { // 避免在起始点绘制尾巴
                ctx.beginPath();
                // 再次使用贝塞尔曲线，但位置略有不同以创建尾部效果
                const tailT = Math.max(0, t - 0.05); // 尾部位置
                const tailX = (1 - tailT) * (1 - tailT) * posX + 2 * (1 - tailT) * tailT * midX + tailT * tailT * targetPosX;
                const tailY = (1 - tailT) * (1 - tailT) * posY + 2 * (1 - tailT) * tailT * midY + tailT * tailT * targetPosY;

                const tailGradient = ctx.createLinearGradient(tailX, tailY, pulseX, pulseY);
                tailGradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
                tailGradient.addColorStop(1, this.adjustColorOpacity(enhancedColor, pulse.opacity * 0.6 * globalPulseEffect));

                ctx.strokeStyle = tailGradient;
                ctx.lineWidth = currentSize * 0.7;
                ctx.moveTo(tailX, tailY);
                ctx.lineTo(pulseX, pulseY);
                ctx.stroke();
              }
            });

            // 随机创建新脉冲 - 增加生成机率，创造更活跃的电路感
            if (connection.pulses.length < 3 && Math.random() > 0.99) {
              const genPulseChance = 0.5 + Math.sin(time + index + connection.targetIndex) * 0.3;

              // 性能优化：根据性能等级调整脉冲生成
              const pulseCreationChance = [0.998, 0.99, 0.98][this.performanceLevel] || 0.998;
              if (connection.pulses.length < (this.performanceLevel + 1) && Math.random() > pulseCreationChance) {
                // 创建新脉冲，增强大小和亮度变化
                connection.pulses.push({
                  position: 0,
                  size: Math.random() * 3 + 1.5,
                  opacity: Math.random() * 0.7 + 0.3,
                  speed: connection.speed * (0.8 + Math.random() * 0.4) // 每个脉冲稍微不同的速度
                });
              }
            }
          }
        });

        // 偶尔在节点间创建电弧特效
        if (this.performanceLevel > 1 && Math.random() > 0.995 && node.connections.length > 0) {
          // 随机选择一个连接创建电弧
          const randomConnIndex = Math.floor(Math.random() * node.connections.length);
          const targetNode = this.circuitNodes[node.connections[randomConnIndex].targetIndex];

          if (targetNode) {
            // 绘制闪电电弧
            ctx.beginPath();
            ctx.strokeStyle = this.adjustColorOpacity(this.adjustColorBrightness(enhancedColor, 80), 0.7);
            ctx.lineWidth = 1.5;

            // 创建锯齿形闪电路径
            const steps = 8;
            let prevX = posX;
            let prevY = posY;

            for (let i = 1; i <= steps; i++) {
              // 线路上的一个点
              const stepT = i / steps;
              // 基本线插值
              const baseX = posX + (targetNode.x - posX) * stepT;
              const baseY = posY + (targetNode.y - posY) * stepT;

              // 给每个点添加随机偏移，但起点和终点不偏移
              let jitterX = 0;
              let jitterY = 0;
              if (i > 1 && i < steps) {
                const jitterAmount = 10 * (1 - Math.abs(stepT - 0.5) * 2); // 中间点偏移最大
                jitterX = (Math.random() - 0.5) * jitterAmount;
                jitterY = (Math.random() - 0.5) * jitterAmount;
              }

              const pointX = baseX + jitterX;
              const pointY = baseY + jitterY;

              // 绘制线段
              ctx.moveTo(prevX, prevY);
              ctx.lineTo(pointX, pointY);

              prevX = pointX;
              prevY = pointY;
            }

            // 绘制闪电
            ctx.stroke();

            // 添加发光效果
            ctx.shadowColor = enhancedColor;
            ctx.shadowBlur = 10;
            ctx.stroke();
            ctx.shadowBlur = 0;
          }
        }
      });
    },

    /**
     * 绘制能量脉冲
     */
    drawEnergyPulses(ctx, canvas) {
      if (!this.energyPulses) return;

      this.energyPulses.forEach(pulse => {
        if (pulse.active) {
          // 更新半径
          pulse.radius += pulse.speed;

          // 计算透明度（随着半径增大而减小）
          const normalizedRadius = Math.min(1, pulse.radius / pulse.maxRadius);
          pulse.opacity = Math.max(0, 0.8 - normalizedRadius);

          // 绘制脉冲环
          ctx.beginPath();
          const gradient = ctx.createRadialGradient(
            pulse.x, pulse.y, pulse.radius * 0.8,
            pulse.x, pulse.y, pulse.radius
          );

          gradient.addColorStop(0, 'rgba(255, 255, 255, 0)');
          gradient.addColorStop(0.5, this.adjustColorOpacity(pulse.color, pulse.opacity * 0.3));
          gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');

          ctx.fillStyle = gradient;
          ctx.arc(pulse.x, pulse.y, pulse.radius, 0, Math.PI * 2);
          ctx.fill();

          // 当半径超过最大半径时重置
          if (pulse.radius >= pulse.maxRadius) {
            pulse.active = false;
          }
        }
      });
    },

    /**
     * 更新和绘制粒子
     */
    updateAndDrawParticles(ctx, canvas, time) {
      if (!ctx || !canvas) return;

      const mouseInteractionRadius = 180; // 鼠标交互半径

      // 更新流向中心点位置
      if (this.flowCenters) {
        this.flowCenters.forEach(center => {
          // 让中心点缓慢移动
          center.x += center.speedX;
          center.y += center.speedY;

          // 边界检查
          if (center.x < 0 || center.x > canvas.width) center.speedX *= -1;
          if (center.y < 0 || center.y > canvas.height) center.speedY *= -1;

          // 随时间变化强度，创造脉动效果
          center.currentStrength = center.strength * (0.7 + 0.3 * Math.sin(time / center.cycleTime * Math.PI * 2));
        });
      }

      // 创建辉光效果的离屏Canvas
      const glowCanvas = this.glowCanvas;
      const glowCtx = this.glowCtx;
      if (!glowCtx) return

      glowCtx.clearRect(0, 0, glowCanvas.width, glowCanvas.height);

      // 性能优化：重用四叉树而不是每次创建新的
      if (!this.particleQuadTree) {
        const boundary = new Rectangle(canvas.width / 2, canvas.height / 2, canvas.width / 2, canvas.height / 2);
        this.particleQuadTree = new QuadTree(boundary, 4);
      } else {
        this.particleQuadTree.clear();
      }

      // 重新构建四叉树
      for (let i = 0; i < this.particles.length; i++) {
        this.particleQuadTree.insert(this.particles[i]);
      }

      // 性能优化：预计算一些常量
      const maxSpeed = 2.5;
      const t = time * 0.001;
      const mousePosition = this.mousePosition;
      const performanceLevel = this.performanceLevel;

      for (let i = 0; i < this.particles.length; i++) {
        const particle = this.particles[i];

        // 更新粒子年龄
        particle.age++;

        // 如果粒子到达生命周期，则重生
        if (particle.age > particle.lifespan) {
          particle.respawn(canvas.width, canvas.height);
          continue;
        }

        // 计算生命周期中的归一化年龄(0-1)
        const normalizedAge = particle.age / particle.lifespan;

        // 基于生命周期调整透明度 - 淡入淡出效果
        if (normalizedAge < 0.1) {
          // 淡入阶段
          particle.opacity = Math.min(particle.opacity, normalizedAge * 10 * (Math.random() * 0.6 + 0.4));
        } else if (normalizedAge > 0.85) {
          // 淡出阶段
          particle.opacity = particle.opacity * 0.98;
        }

        // 应用群组行为 - 相同群组的粒子会受到相似的力
        const groupInfluence = Math.sin(time / 2000 + particle.group) * 0.0015;
        particle.vx += Math.cos(particle.flowDirection + particle.group) * groupInfluence;
        particle.vy += Math.sin(particle.flowDirection + particle.group) * groupInfluence;

        // 应用流向中心点的影响
        if (this.flowCenters) {
          for (let j = 0; j < this.flowCenters.length; j++) {
            const center = this.flowCenters[j];
            const dx = center.x - particle.x;
            const dy = center.y - particle.y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            if (distance < center.radius) {
              // 流体涡旋效果 - 粒子围绕中心点旋转
              const angle = Math.atan2(dy, dx) + Math.PI / 2; // 旋转力方向垂直于中心方向
              const force = (center.radius - distance) / center.radius * center.currentStrength;

              // 应用旋转力
              particle.vx += Math.cos(angle) * force;
              particle.vy += Math.sin(angle) * force;

              // 额外应用一点向中心的引力
              const centerAttraction = force * 0.2;
              particle.vx += dx / distance * centerAttraction;
              particle.vy += dy / distance * centerAttraction;
            }
          }
        }

        // 根据流向添加微小的持续力，创造流动感
        const flowFactor = 0.03; // 增大流动力度
        const cyclicInfluence = Math.sin(t * particle.flowCycle + particle.seed) * particle.flowStrength;

        // 添加更复杂的波动影响
        if (performanceLevel > 0) {
          const wavex = Math.sin(particle.y * 0.01 + t * 0.5) * 0.003;
          const wavey = Math.cos(particle.x * 0.01 + t * 0.5) * 0.003;

          particle.vx += (Math.cos(particle.flowDirection) * cyclicInfluence + wavex) * flowFactor;
          particle.vy += (Math.sin(particle.flowDirection) * cyclicInfluence + wavey) * flowFactor;
        } else {
          // Simplified physics for low performance
          particle.vx += Math.cos(particle.flowDirection) * cyclicInfluence * flowFactor;
          particle.vy += Math.sin(particle.flowDirection) * cyclicInfluence * flowFactor;
        }

        // 随机微弱湍流 - 性能优化：减少随机计算
        if (performanceLevel > 1 && particle.turbulenceTime <= 0) {
          particle.vx += (Math.random() * 0.06 - 0.03);
          particle.vy += (Math.random() * 0.06 - 0.03);
          // 设置下一次湍流时间
          particle.turbulenceTime = Math.floor(Math.random() * 30) + 20;
        } else if (particle.turbulenceTime > 0) {
          particle.turbulenceTime--;
        }

        // 更新位置，应用局部流体阻力
        const dragCoefficient = 0.992 - groupInfluence * 10; // 分组特性影响阻力
        particle.x += particle.vx;
        particle.y += particle.vy;
        particle.vx *= dragCoefficient;
        particle.vy *= dragCoefficient;

        // 边界处理 - 平滑环绕过渡
        const margin = 50;
        if (particle.x < -margin) {
          if (Math.random() > 0.5) {
            // 50%几率重生到右侧
            particle.x = canvas.width + margin * Math.random();
            particle.y = Math.random() * canvas.height;
          } else {
            // 50%几率反弹
            particle.x = -margin * Math.random();
            particle.vx *= -0.5;
          }
        } else if (particle.x > canvas.width + margin) {
          if (Math.random() > 0.5) {
            // 50%几率重生到左侧
            particle.x = -margin * Math.random();
            particle.y = Math.random() * canvas.height;
          } else {
            // 50%几率反弹
            particle.x = canvas.width + margin * Math.random();
            particle.vx *= -0.5;
          }
        }

        if (particle.y < -margin) {
          if (Math.random() > 0.5) {
            // 50%几率重生到底部
            particle.y = canvas.height + margin * Math.random();
            particle.x = Math.random() * canvas.width;
          } else {
            // 50%几率反弹
            particle.y = -margin * Math.random();
            particle.vy *= -0.5;
          }
        } else if (particle.y > canvas.height + margin) {
          if (Math.random() > 0.5) {
            // 50%几率重生到顶部
            particle.y = -margin * Math.random();
            particle.x = Math.random() * canvas.width;
          } else {
            // 50%几率反弹
            particle.y = canvas.height + margin * Math.random();
            particle.vy *= -0.5;
          }
        }

        // 添加鼠标交互效果 - 增强交互响应
        if (mousePosition) {
          const dx = particle.x - mousePosition.x;
          const dy = particle.y - mousePosition.y;
          const distance = Math.sqrt(dx * dx + dy * dy);

          if (distance < mouseInteractionRadius) {
            // 创建涟漪效果：距离越近，力量越大
            const force = (mouseInteractionRadius - distance) / mouseInteractionRadius;
            const angle = Math.atan2(dy, dx);

            // 根据粒子组决定是靠近鼠标还是远离鼠标
            const attract = particle.group % 2 === 0;
            const strength = attract ? -0.8 : 1.2; // 负值吸引，正值排斥

            // 应用力
            particle.vx += Math.cos(angle) * force * strength;
            particle.vy += Math.sin(angle) * force * strength;
          }
        }

        // 限制粒子最大速度
        const speed = Math.sqrt(particle.vx * particle.vx + particle.vy * particle.vy);
        if (speed > maxSpeed) {
          particle.vx = (particle.vx / speed) * maxSpeed;
          particle.vy = (particle.vy / speed) * maxSpeed;
        }

        // 增强粒子视觉效果 - 使时间脉动更明显
        const pulseFactor = 0.6 + Math.sin(time * 0.002 + particle.seed) * 0.4; // 增大脉动幅度
        const speedFactor = Math.min(1, speed / maxSpeed); // 速度越快，颜色越亮
        const displaySize = particle.size * (0.9 + pulseFactor * 0.3); // 增大基础粒子尺寸

        // 增强辉光效果到离屏canvas
        const glowSize = displaySize * 3.2; // 增大辉光尺寸提高可见度
        const gradient = glowCtx.createRadialGradient(
          particle.x, particle.y, 0,
          particle.x, particle.y, glowSize
        );
        const particleColor = particle.color;

        // 使用双层渐变增强辉光
        gradient.addColorStop(0, this.adjustColorOpacity(particleColor, particle.opacity * 0.4)); // 增加核心亮度
        gradient.addColorStop(0.4, this.adjustColorOpacity(particleColor, particle.opacity * 0.25)); // 添加中间过渡层
        gradient.addColorStop(1, 'rgba(0,0,0,0)');

        glowCtx.beginPath();
        glowCtx.fillStyle = gradient;
        glowCtx.arc(particle.x, particle.y, glowSize, 0, Math.PI * 2);
        glowCtx.fill();

        // 绘制粒子核心 - 增强视觉效果
        ctx.beginPath();
        ctx.arc(particle.x, particle.y, displaySize, 0, Math.PI * 2);

        // 根据速度调整粒子颜色亮度 - 增加亮度提升
        const brighterColor = this.adjustColorBrightness(particleColor, 35 * speedFactor); // 增加亮度
        ctx.fillStyle = brighterColor;

        // 调整透明度考虑粒子年龄 - 增强整体可见度
        ctx.globalAlpha = particle.opacity * (0.85 + Math.sin(time * 0.001 + particle.seed) * 0.15); // 提高基础透明度
        ctx.fill();

        // 添加内部发光效果增强核心可见度
        ctx.beginPath();
        ctx.arc(particle.x, particle.y, displaySize * 0.7, 0, Math.PI * 2);
        ctx.fillStyle = this.adjustColorBrightness(particleColor, 50 * speedFactor);
        ctx.fill();

        ctx.globalAlpha = 1;

        // 增强轨迹余辉效果
        if (performanceLevel > 0 && speed > maxSpeed * 0.4) { // 降低速度阈值，让更多粒子显示轨迹
          ctx.beginPath();
          const trailLength = speed / maxSpeed * 25 + 8; // 增加轨迹长度

          ctx.moveTo(particle.x, particle.y);
          ctx.lineTo(
            particle.x - particle.vx * trailLength,
            particle.y - particle.vy * trailLength
          );

          // 增强轨迹可见度
          ctx.strokeStyle = this.adjustColorOpacity(brighterColor, particle.opacity * 0.5 * speed / maxSpeed); // 增加轨迹透明度
          ctx.lineWidth = displaySize * 0.9; // 增加轨迹宽度
          ctx.stroke();
        }

        // 连接邻近粒子 - 使用四叉树查询
        this.connectNearbyParticles(ctx, particle, this.particleQuadTree);

        // 增强辉光效果到离屏canvas
        const glowSprite = this.particleGlows[particle.color];
        if (glowSprite) {
          const glowSize = displaySize * 3.5; // 调整辉光视觉尺寸
          try {
            // 使用 globalAlpha 控制粒子整体的淡入淡出
            glowCtx.globalAlpha = particle.opacity * 0.8;
            glowCtx.drawImage(
              glowSprite,
              particle.x - glowSize / 2,
              particle.y - glowSize / 2,
              glowSize,
              glowSize
            );
            // 重置 globalAlpha
            glowCtx.globalAlpha = 1;
          } catch (e) {
            // 在极少数情况下，图片可能还未完全准备好
            console.error("Failed to draw particle glow:", e);
          }
        }
      }

      // 将辉光效果渲染到主Canvas
      ctx.globalCompositeOperation = 'lighter';
      ctx.drawImage(glowCanvas, 0, 0);
      ctx.globalCompositeOperation = 'source-over';
    },

    /**
     * 连接邻近粒子
     */
    connectNearbyParticles(ctx, particle, qtree) {
      const maxDistance = particle.connectDistance;
      const range = new Rectangle(particle.x, particle.y, maxDistance, maxDistance);
      const nearbyParticles = qtree.query(range);

      for (const otherParticle of nearbyParticles) {
        // 确保只连接一次，并且不连接自身
        if (particle.id >= otherParticle.id) {
          continue;
        }

        const dx = particle.x - otherParticle.x;
        const dy = particle.y - otherParticle.y;
        const distance = Math.sqrt(dx * dx + dy * dy);
        const maxDistance = particle.connectDistance;

        if (distance < maxDistance) {
          // 随着距离变化透明度 - 增强连接线可见度
          const opacity = this.isDarkMode ?
            0.25 * (1 - distance / maxDistance) // 提高深色模式下连接线不透明度
            :
            0.15 * (1 - distance / maxDistance); // 提高亮色模式下连接线不透明度

          ctx.beginPath();
          const color1 = this.parseColor(particle.color);
          const color2 = this.parseColor(otherParticle.color);
          const blendedColor = this.blendColors(color1, color2, 0.5);
          ctx.strokeStyle = this.rgbToString(blendedColor, opacity);
          ctx.lineWidth = 1.2; // 增加连接线宽度提高可见性
          ctx.moveTo(particle.x, particle.y);
          ctx.lineTo(otherParticle.x, otherParticle.y);
          ctx.stroke();
        }
      }
    },

    /**
     * 绘制流体斑点 - 完全重写以提高流动性
     */
    drawFluidBlobs(ctx, canvas, time) {
      if (!ctx || !canvas) return;

      const t = time * 0.001;
      const displayWidth = this.displayWidth || canvas.width;
      const displayHeight = this.displayHeight || canvas.height;
      const performanceLevel = this.performanceLevel;

      // 性能优化：根据性能等级调整绘制的斑点数量
      const blobLimit = [Math.ceil(this.blobs.length * 0.5), Math.ceil(this.blobs.length * 0.75), this.blobs.length][performanceLevel] || Math.ceil(this.blobs.length * 0.5);

      // 性能优化：使用for循环替代forEach
      for (let i = 0; i < blobLimit; i++) {
        const blob = this.blobs[i];

        // 使用不同的流动模式创建更多样化的运动
        let x, y;

        switch (blob.flowPattern) {
          case 0: // Lissajous curves - 更复杂的曲线
            x = displayWidth * 0.5 + Math.cos(t * blob.speed * 0.7 + blob.seed) * displayWidth * 0.4 +
              Math.sin(t * blob.speed * 0.3 + blob.phaseOffset) * displayWidth * 0.15;
            y = displayHeight * 0.5 + Math.sin(t * blob.speed * 0.6 + blob.seed) * displayHeight * 0.35 +
              Math.cos(t * blob.speed * 0.5 + blob.phaseOffset) * displayHeight * 0.12;
            break;

          case 1: // 螺旋模式
            const spiralRadius = Math.min(displayWidth, displayHeight) * 0.3;
            const spiralFactor = (1 + Math.sin(t * 0.2)) * 0.5;
            const currentRadius = spiralRadius * spiralFactor;
            const spiralAngle = t * blob.speed * 0.5 + blob.seed;

            x = displayWidth * 0.5 + Math.cos(spiralAngle) * currentRadius;
            y = displayHeight * 0.5 + Math.sin(spiralAngle) * currentRadius;
            break;

          case 2: // 波浪模式
            x = (t * 20 * blob.speed) % (displayWidth + 300) - 150;
            y = displayHeight * 0.5 + Math.sin(t * blob.speed * 2 + blob.seed) * displayHeight * 0.3;
            break;

          case 3: // 超大型缓慢模式
            // 使用Perlin噪声效果，模拟更自然的运动
            const noiseScale = 0.3;
            const noiseTime = t * 0.1;
            const noiseX = Math.cos(t * blob.speed * 0.2 + blob.seed) * noiseScale;
            const noiseY = Math.sin(t * blob.speed * 0.15 + blob.phaseOffset) * noiseScale;

            x = displayWidth * (0.3 + 0.4 * (Math.sin(noiseX + noiseTime) * 0.5 + 0.5));
            y = displayHeight * (0.3 + 0.4 * (Math.cos(noiseY + noiseTime) * 0.5 + 0.5));
            break;

          default:
            x = blob.x;
            y = blob.y;
        }

        blob.x = x;
        blob.y = y;

        // 性能优化：检查斑点是否在可视区域内
        const maxRadius = blob.radius * 1.5;
        if (
          x + maxRadius < 0 ||
          x - maxRadius > displayWidth ||
          y + maxRadius < 0 ||
          y - maxRadius > displayHeight
        ) {
          continue; // 跳过不在可视区域内的斑点
        }

        // 更新斑点旋转
        blob.rotation += blob.rotationSpeed;

        // 添加多重脉冲效果 - 性能优化：简化计算
        const pulseEffect = Math.sin(t * blob.pulseSpeed * 2) * blob.pulseAmplitude + 1;
        const secondaryPulse = Math.sin(t * blob.pulseSpeed * 1.3 + blob.phaseOffset) * blob.pulseAmplitude * 0.5 + 0.5;
        // 性能优化：在低性能模式下跳过第三层脉冲
        const tertiaryPulse = performanceLevel > 0 ?
          Math.sin(t * blob.pulseSpeed * 0.7 + blob.seed * 2) * blob.pulseAmplitude * 0.3 + 0.3 : 0.3;
        const combinedPulse = (pulseEffect + secondaryPulse + tertiaryPulse) * 0.5;

        const currentRadius = blob.radius * (0.85 + combinedPulse * 0.25);

        // 创建离屏canvas来绘制斑点，以应用更多效果
        const blobCanvas = blob.canvas;
        const blobCtx = blob.ctx;

        // 如果无法获取上下文，则跳过
        if (!blobCtx) continue;
        blobCtx.clearRect(0, 0, blobCanvas.width, blobCanvas.height);

        // 确定斑点在离屏canvas中的中心点
        const centerX = blobCanvas.width / 2;
        const centerY = blobCanvas.height / 2;

        // 绘制斑点 - 使用多层渐变添加更多深度
        const gradient = blobCtx.createRadialGradient(
          centerX, centerY, 0,
          centerX, centerY, currentRadius
        );

        // 添加更多渐变色阶
        const currentOpacity = blob.opacity * (0.8 + Math.sin(t * 0.5 + blob.seed) * 0.2);

        // 添加颜色变异 - 性能优化：在低性能模式下简化颜色变异
        const colorVariation = performanceLevel > 0 ?
          blob.colorVariation * Math.sin(t * 0.2 + blob.seed) : 0;
        const baseColor = blob.color;
        const variedColor = colorVariation !== 0 ?
          this.adjustColorBrightness(baseColor, colorVariation) : baseColor;

        // 性能优化：根据性能等级调整渐变复杂度
        if (performanceLevel < 2) {
          // 简化版渐变
          gradient.addColorStop(0, this.adjustColorOpacity(variedColor, currentOpacity * 1.6));
          gradient.addColorStop(0.5, this.adjustColorOpacity(baseColor, currentOpacity * 0.6));
          gradient.addColorStop(1, this.adjustColorOpacity(baseColor, 0));
        } else {
          // 完整版渐变
          gradient.addColorStop(0, this.adjustColorOpacity(variedColor, currentOpacity * 1.8));
          gradient.addColorStop(0.3, this.adjustColorOpacity(variedColor, currentOpacity * 1.4));
          gradient.addColorStop(0.6, this.adjustColorOpacity(baseColor, currentOpacity * 0.8));
          gradient.addColorStop(0.8, this.adjustColorOpacity(baseColor, currentOpacity * 0.3));
          gradient.addColorStop(1, this.adjustColorOpacity(baseColor, 0));
        }

        blobCtx.fillStyle = gradient;
        blobCtx.beginPath();

        // 创建更有机的形状 - 性能优化：根据性能等级调整点的数量
        const pointMultiplier = [0.8, 1.2, 1.5][this.performanceLevel] || 0.8;
        const points = Math.floor(blob.distortionCount * pointMultiplier);

        // 第一个点
        blobCtx.moveTo(
          centerX + Math.cos(blob.rotation) * currentRadius,
          centerY + Math.sin(blob.rotation) * currentRadius
        );

        // 性能优化：预计算扭曲效果
        const distortions = new Array(points + 1);
        for (let i = 0; i <= points; i++) {
          const angle = (i / points) * Math.PI * 2 + blob.rotation;

          // 计算扭曲效果
          let distortion = 0;
          // 性能优化：使用for循环替代forEach
          for (let j = 0; j < blob.distortions.length; j++) {
            const d = blob.distortions[j];
            const angleDiff = Math.abs(((angle - d.angle + Math.PI) % (Math.PI * 2)) - Math.PI);
            const influence = Math.max(0, 1 - angleDiff / (Math.PI * 0.5));
            distortion += Math.sin(t * d.speed + d.offset) * d.strength * influence;
          }

          distortions[i] = distortion;
        }

        // 绘制形状点
        for (let i = 1; i <= points; i++) {
          const angle = (i / points) * Math.PI * 2 + blob.rotation;
          const prevAngle = ((i - 1) / points) * Math.PI * 2 + blob.rotation;

          // 应用脉冲和扭曲
          const distortion = distortions[i];
          const prevDistortion = distortions[i - 1];

          const radiusVariation = currentRadius * (1 + distortion + Math.sin(angle * 3 + t * 0.7) * 0.05);
          const prevRadius = currentRadius * (1 + prevDistortion + Math.sin(prevAngle * 3 + t * 0.7) * 0.05);

          const x = centerX + Math.cos(angle) * radiusVariation;
          const y = centerY + Math.sin(angle) * radiusVariation;
          const prevX = centerX + Math.cos(prevAngle) * prevRadius;
          const prevY = centerY + Math.sin(prevAngle) * prevRadius;

          // 性能优化：根据性能等级选择使用贝塞尔曲线或直线
          if (performanceLevel > 0) {
            // 使用贝塞尔曲线创建更平滑的形状
            const cp1x = prevX + (x - prevX) * 0.5 - (y - prevY) * 0.2;
            const cp1y = prevY + (y - prevY) * 0.5 + (x - prevX) * 0.2;
            const cp2x = x - (x - prevX) * 0.5 - (y - prevY) * 0.2;
            const cp2y = y - (y - prevY) * 0.5 + (x - prevX) * 0.2;

            blobCtx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
          } else {
            // 低性能模式下使用直线
            blobCtx.lineTo(x, y);
          }
        }

        blobCtx.closePath();
        blobCtx.fill();

        // 添加光晕边缘效果 - 只在中高性能模式下启用
        if (performanceLevel > 0) {
          blobCtx.globalCompositeOperation = 'screen';
          const edgeGlow = blobCtx.createRadialGradient(
            centerX, centerY, currentRadius * 0.85,
            centerX, centerY, currentRadius * 1.05
          );
          edgeGlow.addColorStop(0, 'rgba(255,255,255,0)');
          edgeGlow.addColorStop(0.5, this.adjustColorOpacity(this.adjustColorBrightness(baseColor, 40), 0.15));
          edgeGlow.addColorStop(1, 'rgba(255,255,255,0)');

          blobCtx.fillStyle = edgeGlow;
          blobCtx.beginPath();
          blobCtx.arc(centerX, centerY, currentRadius * 1.05, 0, Math.PI * 2);
          blobCtx.fill();
        }

        // 将离屏canvas绘制到主canvas
        ctx.globalCompositeOperation = 'lighten';
        ctx.drawImage(
          blobCanvas,
          blob.x - blobCanvas.width / 2,
          blob.y - blobCanvas.height / 2
        );
        ctx.globalCompositeOperation = 'source-over';
      }
    },

    /**
     * 绘制光晕点
     */
    drawGlowPoints(ctx, canvas, time) {
      if (!ctx || !canvas) return;

      const t = time * 0.001;

      this.glowPoints.forEach(point => {
        // 基于不同的运动模式更新位置
        let x, y;
        switch (point.movementType) {
          case 0: // 圆形路径
            x = canvas.width / 2 + Math.cos(t * point.speed) * point.distance;
            y = canvas.height / 2 + Math.sin(t * point.speed) * point.distance;
            break;

          case 1: // 八字形路径 (Lissajous曲线)
            x = canvas.width / 2 +
              Math.sin(t * point.speed * 0.7 + point.seed) * point.distance * 1.2;
            y = canvas.height / 2 +
              Math.sin(t * point.speed * 1.3 + point.seed) * point.distance * 0.8;
            break;

          case 2: // 随机有束缚的运动
            // 使用正弦和余弦函数创建类似布朗运动的效果
            const noiseScale = 0.5;
            const noiseX = Math.sin(t * 0.3 + point.seed * 10) * noiseScale +
              Math.cos(t * 0.7 + point.seed * 5) * noiseScale;
            const noiseY = Math.cos(t * 0.4 + point.seed * 15) * noiseScale +
              Math.sin(t * 0.6 + point.seed * 7) * noiseScale;

            x = canvas.width * (0.3 + 0.4 * (Math.sin(noiseX) * 0.5 + 0.5));
            y = canvas.height * (0.3 + 0.4 * (Math.cos(noiseY) * 0.5 + 0.5));
            break;

          default:
            x = point.x;
            y = point.y;
        }

        point.x = x;
        point.y = y;

        // 脉冲效果
        const pulseFactor = 0.8 + Math.sin(t * point.pulseFrequency) * 0.2;
        const currentOpacity = point.opacity * pulseFactor;
        const currentSize = point.size * pulseFactor;

        // 优化：使用预渲染的辉光贴图进行绘制
        const glowSprite = this.particleGlows[point.color];
        if (glowSprite) {
          ctx.globalAlpha = currentOpacity;
          ctx.drawImage(
            glowSprite,
            x - currentSize / 2,
            y - currentSize / 2,
            currentSize,
            currentSize
          );
          ctx.globalAlpha = 1;
        }
      });
    },

    /**
     * 混合两种颜色
     */
    blendColors(color1, color2, factor) {
      // 优化：直接处理颜色对象，而不是每次都解析字符串
      const r = Math.round(color1.r * (1 - factor) + color2.r * factor);
      const g = Math.round(color1.g * (1 - factor) + color2.g * factor);
      const b = Math.round(color1.b * (1 - factor) + color2.b * factor);

      return {
        r,
        g,
        b
      };
    },

    /**
     * 调整颜色透明度
     */
    adjustColorOpacity(color, opacity) {
      if (color.startsWith('rgba')) {
        const parts = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
        if (parts) {
          return `rgba(${parts[1]}, ${parts[2]}, ${parts[3]}, ${opacity})`;
        }
      } else if (color.startsWith('rgb')) {
        const parts = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
        if (parts) {
          return `rgba(${parts[1]}, ${parts[2]}, ${parts[3]}, ${opacity})`;
        }
      } else if (color.startsWith('#')) {
        let hex = color.substring(1);
        let r, g, b;

        if (hex.length === 3) {
          r = parseInt(hex[0] + hex[0], 16);
          g = parseInt(hex[1] + hex[1], 16);
          b = parseInt(hex[2] + hex[2], 16);
        } else {
          r = parseInt(hex.substring(0, 2), 16);
          g = parseInt(hex.substring(2, 4), 16);
          b = parseInt(hex.substring(4, 6), 16);
        }

        return `rgba(${r}, ${g}, ${b}, ${opacity})`;
      }

      return color;
    },

    /**
     * 检查当前主题
     */
    checkCurrentTheme() {
      const isDark = document.body.classList.contains('dark-theme') ||
        this.$store.state.theme === 'dark';
      this.isDarkMode = isDark;
    },

    /**
     * 更新背景颜色
     */
    updateBackgroundColors(theme) {
      this.isDarkMode = theme === 'dark';
    },

    /**
     * 调整颜色亮度
     */
    adjustColorBrightness(color, percent) {
      // 解析颜色
      let r, g, b;

      if (color.startsWith('rgba')) {
        const parts = color.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/);
        if (parts) {
          r = parseInt(parts[1]);
          g = parseInt(parts[2]);
          b = parseInt(parts[3]);
        }
      } else if (color.startsWith('rgb')) {
        const parts = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
        if (parts) {
          r = parseInt(parts[1]);
          g = parseInt(parts[2]);
          b = parseInt(parts[3]);
        }
      } else if (color.startsWith('#')) {
        let hex = color.substring(1);
        if (hex.length === 3) {
          r = parseInt(hex[0] + hex[0], 16);
          g = parseInt(hex[1] + hex[1], 16);
          b = parseInt(hex[2] + hex[2], 16);
        } else {
          r = parseInt(hex.substring(0, 2), 16);
          g = parseInt(hex.substring(2, 4), 16);
          b = parseInt(hex.substring(4, 6), 16);
        }
      } else {
        return color; // 不支持的颜色格式，返回原色
      }

      // 调整亮度
      r = Math.min(255, Math.max(0, Math.round(r + percent)));
      g = Math.min(255, Math.max(0, Math.round(g + percent)));
      b = Math.min(255, Math.max(0, Math.round(b + percent)));

      return `rgb(${r}, ${g}, ${b})`;
    },

    /**
     * 为数字雨列生成字符
     */
    generateCharsForColumn(column) {
      column.chars = [];

      for (let j = 0; j < column.length; j++) {
        // 优化：调用统一的函数获取随机字符，避免代码重复
        const char = this.getRandomCharForType(column.charType);

        // 添加一个亮度属性，用于创建字符的淡入淡出效果
        const brightness = j === 0 ? 1.0 : Math.max(0.4, 1 - (j / column.length));

        column.chars.push({
          value: char,
          brightness: brightness,
          changed: Date.now() // 记录字符最后变化的时间
        });
      }
    },

    /**
     * 新增：解析颜色字符串为对象
     */
    parseColor(color) {
      if (color.startsWith('#')) {
        let hex = color.substring(1);
        if (hex.length === 3) {
          hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
        }
        return {
          r: parseInt(hex.substring(0, 2), 16),
          g: parseInt(hex.substring(2, 4), 16),
          b: parseInt(hex.substring(4, 6), 16),
        };
      }
      const match = color.match(/\d+/g);
      if (match && match.length >= 3) {
        return {
          r: parseInt(match[0]),
          g: parseInt(match[1]),
          b: parseInt(match[2])
        };
      }
      return {
        r: 0,
        g: 0,
        b: 0
      }; // 默认
    },

    /**
     * 新增：将颜色对象转换为rgba字符串
     */
    rgbToString(color, opacity = 1) {
      return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity})`;
    },

    /**
     * 新增：处理颜色对象的亮度调整
     */
    adjustColorBrightnessObj(colorObj, percent) {
      return {
        r: Math.min(255, Math.max(0, Math.round(colorObj.r + percent))),
        g: Math.min(255, Math.max(0, Math.round(colorObj.g + percent))),
        b: Math.min(255, Math.max(0, Math.round(colorObj.b + percent))),
      }
    },

    /**
     * 为数字雨链生成字符
     */
    generateCharsForChain(chain, charType) {
      chain.chars = [];

      for (let j = 0; j < chain.length; j++) {
        // 获取随机字符
        const char = this.getRandomCharForType(charType);

        // 添加亮度属性，用于淡入淡出效果
        const brightness = j === 0 ? 1.0 : Math.max(0.4, 1 - (j / chain.length));

        chain.chars.push({
          value: char,
          brightness: brightness,
          changed: Date.now() // 记录字符最后变化的时间
        });
      }
    },
  },
  beforeDestroy() {
    enableScroll();
    this.clearTimer();

    // 清除背景动画
    if (this.animationFrameId) {
      cancelAnimationFrame(this.animationFrameId);
    }

    // 清除能量脉冲定时器
    if (this.pulseIntervalId) {
      clearInterval(this.pulseIntervalId);
    }
  },
};
</script>

<style scoped lang="scss">
@use "sass:color";

.login-container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  z-index: 2000;
}

.animated-background {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.background-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.floating-shapes {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  overflow: hidden;
}

.shape {
  position: absolute;
  border-radius: 50%;
  filter: blur(30px);
  opacity: 0.2;
  animation: float 15s infinite alternate ease-in-out;

  &.shape-1 {
    top: 10%;
    left: 10%;
    width: 300px;
    height: 300px;
    background: radial-gradient(circle, #4299e1 0%, transparent 70%);
    animation-duration: 20s;
  }

  &.shape-2 {
    top: 70%;
    left: 80%;
    width: 250px;
    height: 250px;
    background: radial-gradient(circle, #68d391 0%, transparent 70%);
    animation-duration: 25s;
    animation-delay: 1s;
  }

  &.shape-3 {
    top: 40%;
    left: 25%;
    width: 200px;
    height: 200px;
    background: radial-gradient(circle, #f6ad55 0%, transparent 70%);
    animation-duration: 18s;
    animation-delay: 2s;
  }

  &.shape-4 {
    top: 60%;
    left: 5%;
    width: 350px;
    height: 350px;
    background: radial-gradient(circle, #fc8181 0%, transparent 70%);
    animation-duration: 22s;
    animation-delay: 3s;
  }

  &.shape-5 {
    top: 15%;
    left: 70%;
    width: 280px;
    height: 280px;
    background: radial-gradient(circle, #b794f4 0%, transparent 70%);
    animation-duration: 19s;
    animation-delay: 1.5s;
  }

  &.shape-6 {
    top: 50%;
    left: 50%;
    width: 320px;
    height: 320px;
    background: radial-gradient(circle, #68c2e8 0%, transparent 70%);
    animation-duration: 24s;
    animation-delay: 2.5s;
  }

  &.shape-7 {
    top: 75%;
    left: 30%;
    width: 220px;
    height: 220px;
    background: radial-gradient(circle, #4fd1c5 0%, transparent 70%);
    animation-duration: 26s;
    animation-delay: 0.5s;
  }

  &.shape-8 {
    top: 35%;
    left: 85%;
    width: 260px;
    height: 260px;
    background: radial-gradient(circle, #f687b3 0%, transparent 70%);
    animation-duration: 23s;
    animation-delay: 1s;
  }

  &.shape-9 {
    top: 85%;
    left: 60%;
    width: 240px;
    height: 240px;
    background: radial-gradient(circle, #9f7aea 0%, transparent 70%);
    animation-duration: 21s;
    animation-delay: 1.8s;
  }

  &.shape-10 {
    top: 25%;
    left: 40%;
    width: 280px;
    height: 280px;
    background: radial-gradient(circle, #48bb78 0%, transparent 70%);
    animation-duration: 17s;
    animation-delay: 3.5s;
  }
}

.gradient-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: radial-gradient(circle at center, transparent 0%, rgba(0, 0, 0, 0.05) 100%);
  z-index: 2;
  pointer-events: none;
}

@keyframes float {
  0% {
    transform: translate(0, 0) scale(1);
  }

  50% {
    transform: translate(30px, -30px) scale(1.05);
  }

  100% {
    transform: translate(-30px, 30px) scale(0.95);
  }
}

.login-body {
  width: 420px;
  padding: 32px;
  border-radius: 20px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  background: rgba(255, 255, 255, 0.18); // 降低不透明度，增强透明感
  border: 1px solid rgba(255, 255, 255, 0.22);
  position: relative;
  transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
  transform: translateY(40px);
  opacity: 0;
  overflow: hidden;
  z-index: 10;
  /* 添加新的毛玻璃效果和边缘发光 */
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15),
    0 1px 8px rgba(64, 158, 255, 0.1);

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, #409EFF, #67C23A, #E6A23C, #F56C6C);
    opacity: 0.8; // 降低顶部条带的不透明度
    z-index: 1;
    animation: gradientShift 5s infinite alternate;
    background-size: 300% 100%;
  }

  &:hover {
    transform: translateY(-5px);
    box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15),
      0 2px 12px rgba(64, 158, 255, 0.2);
    background: rgba(255, 255, 255, 0.25); // 悬停时略微增加不透明度
  }

  &.login-body-show {
    transform: translateY(0);
    opacity: 1;
  }
}

.form-container {
  animation: fadeIn 0.3s ease;
  padding: 10px 0;
  position: relative;
}

.form-item {
  margin-bottom: 20px;
  position: relative;
  transition: all 0.3s;

  &:hover {
    transform: translateX(2px);
  }

  :deep(.el-input__inner) {
    height: 48px;
    font-size: 15px;
    border-radius: 12px;
    border: 1px solid rgba(255, 255, 255, 0.3);
    padding-left: 45px;
    background-color: rgba(255, 255, 255, 0.25);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.1);
    transition: all 0.3s;
    color: rgba(128, 127, 127, 0.85);

    &::placeholder {
      color: rgba(161, 161, 161, 0.65); // 提高占位符对比度
      transition: color 0.3s;
      font-weight: 600; // 加粗占位符文字
      letter-spacing: 0.3px; // 增加字间距提高可读性
    }

    &:focus {
      border-color: #409eff;
      background-color: rgba(255, 255, 255, 0.35);
      box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2), 0 4px 8px rgba(0, 0, 0, 0.1);
      transform: translateY(-1px); // 添加微小上移效果
    }
  }

  :deep(.el-input__prefix) {
    left: 15px;
    color: #409eff;
    opacity: 0.9;
    transition: all 0.3s;
  }

  &:hover :deep(.el-input__prefix) {
    transform: scale(1.1);
    opacity: 1;
  }

  :deep(.el-input-group__append) {
    background: #409eff;
    color: white;
    border-color: #409eff;
    border-top-right-radius: 12px;
    border-bottom-right-radius: 12px;

    .el-button {
      color: white;
      border: none;
      background: transparent;
      padding: 0 15px;
      font-weight: 500;
    }
  }
}

.submit-btn {
  width: 100%;
  height: 48px;
  border: none;
  border-radius: 12px;
  background: linear-gradient(135deg, #409eff, #2b85e4);
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
  transition: all 0.4s ease;
  position: relative;
  overflow: hidden;
  box-shadow: 0 4px 10px rgba(43, 133, 228, 0.2), 0 1px 3px rgba(43, 133, 228, 0.1);

  // 添加脉动光效
  &::after {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.25) 0%, transparent 60%);
    opacity: 0;
    transition: opacity 0.8s;
  }

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 15px rgba(43, 133, 228, 0.25), 0 1px 5px rgba(43, 133, 228, 0.15);

    &::after {
      opacity: 1;
      animation: pulse-light 2s infinite;
    }

    &::before {
      left: 100%;
    }
  }

  &:active {
    transform: translateY(1px);
    box-shadow: 0 2px 5px rgba(43, 133, 228, 0.15);
  }
}

@keyframes pulse-light {
  0% {
    transform: scale(0.95);
    opacity: 0.5;
  }

  50% {
    transform: scale(1);
    opacity: 0.8;
  }

  100% {
    transform: scale(0.95);
    opacity: 0.5;
  }
}

.divider {
  margin: 24px 0;
  color: #9ca3af;

  :deep(.el-divider__text) {
    background-color: #fff;
    padding: 0 12px;
    font-size: 14px;
  }
}

.third-party-login {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-bottom: 28px;
  padding: 5px;
}

.login-icon-wrapper {
  position: relative;

  &::after {
    content: '';
    position: absolute;
    bottom: -8px;
    left: 50%;
    transform: translateX(-50%) scaleX(0);
    width: 20px;
    height: 3px;
    background: currentColor;
    transition: transform 0.3s;
    border-radius: 3px;
    opacity: 0.7;
  }

  &:hover::after {
    transform: translateX(-50%) scaleX(1);
  }
}

.login-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  cursor: pointer;
  transition: all 0.3s;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
  position: relative;
  overflow: hidden;

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: currentColor;
    opacity: 0.1;
    transition: opacity 0.3s;
  }

  &:hover {
    transform: translateY(-4px) scale(1.05);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12);
    border-color: rgba(255, 255, 255, 0.4);

    &::before {
      opacity: 0.2;
    }
  }

  &.github {
    color: #24292e;
  }

  &.qq {
    color: #12b7f5;
  }

  &.wechat {
    color: #07c160;
  }

  &.gitee {
    color: #c71d23;
  }

  &.weibo {
    color: #e6162d;
  }
}

.form-switch {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 28px;
  color: #6b7280;
  font-size: 15px;
  position: relative;
  padding: 8px 0;

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 60px;
    height: 1px;
    background: rgba(0, 0, 0, 0.05);
  }

  a {
    color: $primary;
    text-decoration: none;
    font-weight: 600;
    cursor: pointer;
    margin: 0 8px;
    position: relative;
    transition: all 0.3s;
    padding: 2px 8px;
    border-radius: 4px;

    &:hover {
      color: color.adjust($primary, $lightness: 10%);
      background-color: rgba(64, 158, 255, 0.08);
    }

    &::after {
      content: '';
      position: absolute;
      bottom: -2px;
      left: 0;
      width: 100%;
      height: 2px;
      background: currentColor;
      transform: scaleX(0);
      transition: transform 0.3s;
      opacity: 0.6;
    }

    &:hover::after {
      transform: scaleX(1);
    }
  }
}

.divider-line {
  color: #e5e7eb;
  margin: 0 12px;
  opacity: 0.6;
}

.qrcode-content {
  padding: 24px;
  text-align: center;
  animation: fadeIn 0.3s ease;
}

.qrcode-box {
  width: 220px;
  height: 220px;
  margin: 0 auto 16px;
  padding: 10px;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 16px;
  position: relative;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  transition: transform 0.4s ease, box-shadow 0.4s ease;

  &:hover {
    transform: translateY(-5px) scale(1.02);
    box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
    border-color: rgba(255, 255, 255, 0.4);

    .scan-line {
      height: 3px;
      animation-duration: 1.8s;
    }

    .corner {
      border-width: 3px;
    }
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    position: relative;
    z-index: 2;
    border-radius: 12px;
    transition: filter 0.3s ease;
  }

  .corner-decoration {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    pointer-events: none;

    .corner {
      position: absolute;
      width: 32px;
      height: 32px;
      border: 2px solid transparent;
      transition: all 0.3s ease;

      &.top-left {
        top: 10px;
        left: 10px;
        border-top-color: #409EFF;
        border-left-color: #409EFF;
        border-radius: 12px 0 0 0;
      }

      &.top-right {
        top: 10px;
        right: 10px;
        border-top-color: #409EFF;
        border-right-color: #409EFF;
        border-radius: 0 12px 0 0;
      }

      &.bottom-left {
        bottom: 10px;
        left: 10px;
        border-bottom-color: #409EFF;
        border-left-color: #409EFF;
        border-radius: 0 0 0 12px;
      }

      &.bottom-right {
        bottom: 10px;
        right: 10px;
        border-bottom-color: #409EFF;
        border-right-color: #409EFF;
        border-radius: 0 0 12px 0;
      }
    }
  }

  // 中心Logo发光效果
  .center-logo-glow {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 70px;
    height: 70px;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, rgba(64, 158, 255, 0.6) 0%, rgba(255, 255, 255, 0) 70%);
    z-index: 1;
    opacity: 0.6;
    pointer-events: none;
    animation: pulse 2s infinite;
  }

  @keyframes pulse {
    0% {
      transform: translate(-50%, -50%) scale(0.95);
      opacity: 0.4;
    }

    50% {
      transform: translate(-50%, -50%) scale(1.05);
      opacity: 0.7;
    }

    100% {
      transform: translate(-50%, -50%) scale(0.95);
      opacity: 0.4;
    }
  }

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(135deg, rgba(64, 158, 255, 0.06), rgba(64, 158, 255, 0.01));
    border-radius: 16px;
    z-index: 1;
  }

  /* 扫描线动画 */
  .scan-line {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background: linear-gradient(to right,
        rgba(64, 158, 255, 0),
        rgba(64, 158, 255, 0.9) 50%,
        rgba(64, 158, 255, 0));
    box-shadow: 0 0 12px rgba(64, 158, 255, 0.7);
    z-index: 3;
    animation: scanAnimation 2.5s ease-in-out infinite;
    pointer-events: none;
  }

  /* 扫描框 */
  .scan-border {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border: 1px solid rgba(64, 158, 255, 0.3);
    border-radius: 12px;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
  }
}

// 验证码信息样式
.qrcode-info {
  margin-top: 16px;
  text-align: center;

  .code-label {
    font-size: 15px;
    color: #606266;
    margin-bottom: 6px;

    .code-value {
      color: #409EFF;
      font-weight: 600;
      letter-spacing: 1px;
    }
  }

  .code-tip {
    font-size: 14px;
    color: #909399;
  }
}

.qrcode-tip {
  margin: 8px 0;
  color: #6b7280;
  font-size: 14px;
}

/* 扫描线动画 */
@keyframes scanAnimation {
  0% {
    top: 10px;
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  85% {
    opacity: 1;
  }

  100% {
    top: calc(100% - 10px);
    opacity: 0;
  }
}

// 添加微小的动画效果
@keyframes cornerPulse {
  0% {
    border-color: rgba(64, 158, 255, 0.8);
  }

  50% {
    border-color: rgba(64, 158, 255, 0.4);
  }

  100% {
    border-color: rgba(64, 158, 255, 0.8);
  }
}

.corner {
  animation: cornerPulse 2s infinite;
}

/* 深色模式适配 */
.dark-theme {
  .animated-background {
    .gradient-overlay {
      background: radial-gradient(circle at center, transparent 0%, rgba(0, 0, 0, 0.2) 100%);
    }
  }

  .login-body {
    background: rgba(24, 28, 38, 0.65); // 提高深色模式下表单不透明度以增强对比度
    box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3),
      0 10px 10px -5px rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.15); // 提高边框亮度

    &::before {
      background: linear-gradient(90deg, #409EFF, #5abeff, #67C23A, #5abeff, #409EFF);
      opacity: 0.9;
      background-size: 300% 100%;
      animation: gradientShift 3s infinite alternate;
    }

    &:hover {
      box-shadow: 0 20px 30px -8px rgba(0, 0, 0, 0.35),
        0 15px 15px -5px rgba(0, 0, 0, 0.25);
      border-color: rgba(255, 255, 255, 0.2);
      background: rgba(24, 28, 38, 0.7);
    }
  }

  .form-subtitle {
    color: #ccc; // 提高对比度
  }

  .form-header::after {
    background: linear-gradient(90deg, #409EFF, #67C23A);
    opacity: 0.8;
    background-size: 200% 100%;
    animation: gradientShift 3s infinite alternate;
  }

  .form-item {
    :deep(.el-input__inner) {
      background-color: rgba(30, 34, 45, 0.8); // 提高输入框背景不透明度
      border-color: rgba(255, 255, 255, 0.2); // 提高边框可见度
      color: rgba(255, 255, 255, 1); // 确保文字颜色完全不透明
      box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25);

      &::placeholder {
        color: rgba(255, 255, 255, 0.8); // 提高占位符不透明度，增强可见度
        font-weight: 600; // 加粗显示
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); // 添加文字阴影增强可读性
      }

      &:focus {
        border-color: #409eff;
        background-color: rgba(30, 34, 45, 0.85); // 聚焦时增加背景不透明度
        box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.3), 0 3px 8px rgba(0, 0, 0, 0.25);
      }
    }

    :deep(.el-input__prefix) {
      color: #5abeff;
      opacity: 1; // 提高图标不透明度
      filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2)); // 添加图标阴影
    }

    :deep(.el-input-group__append) {
      background: #409eff;
      border-color: #409eff;

      .el-button {
        background: transparent;
        color: white;
        border: none;

        &:hover,
        &:focus {
          background: rgba(255, 255, 255, 0.15); // 提高悬停效果可见度
        }

        &:disabled {
          color: rgba(255, 255, 255, 0.6); // 提高禁用状态可见度
        }
      }
    }
  }

  .form-switch a {
    color: #62b0ff; // 调整亮度更高的蓝色
    font-weight: 700; // 增加字重

    &:hover {
      color: color.adjust(#5eaaff, $lightness: 15%);
      background-color: rgba(64, 158, 255, 0.15);
    }
  }

  .form-options {
    :deep(.el-checkbox__label) {
      color: #ccc; // 提高对比度
    }
  }

  .switch-form-btn,
  .back-btn {
    background: rgba(40, 44, 52, 0.9);
    border: 1px solid rgba(255, 255, 255, 0.12);

    &:hover {
      background: #409eff;
      border-color: #409eff;
    }
  }

  .qrcode-box {
    background: rgba(30, 33, 42, 0.7); // 提高透明度
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25); // 减轻阴影

    &::before {
      background: linear-gradient(135deg, rgba(64, 158, 255, 0.1), rgba(64, 158, 255, 0.04));
    }

    .scan-line {
      box-shadow: 0 0 12px rgba(64, 158, 255, 0.7);
    }

    .corner {
      border-color: rgba(64, 158, 255, 0.6);
    }

    .center-logo-glow {
      background: radial-gradient(circle, rgba(64, 158, 255, 0.25) 0%, rgba(0, 0, 0, 0) 70%);
      opacity: 0.7;
    }

    .scan-border {
      border-color: rgba(64, 158, 255, 0.15);
      background: linear-gradient(135deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.05));
    }
  }

  .qrcode-info {
    .code-label {
      color: #a0a0a0;
    }

    .qrcode-tip {
      color: #98a0b3;
    }
  }

  .third-party-login {
    .login-icon {
      background: rgba(36, 39, 48, 0.8);
      border: 1px solid rgba(255, 255, 255, 0.08);

      &:hover {
        box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
        transform: translateY(-5px) scale(1.05);
        border-color: rgba(255, 255, 255, 0.2);
      }
    }
  }

  .divider {
    :deep(.el-divider__text) {
      background-color: rgba(24, 28, 38, 0.85);
      color: #bbb;
    }
  }

  // 表单提交按钮特效增强
  .submit-btn {
    background: linear-gradient(135deg, #3e8ee0, #246bb3);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);

    &:hover {
      background: linear-gradient(135deg, #409eff, #2b85e4);
      box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
    }
  }
}

@keyframes gradientShift {
  0% {
    background-position: 0% 50%;
  }

  100% {
    background-position: 100% 50%;
  }
}

/* 添加按钮脉动动画 */
@keyframes pulse-btn {
  0% {
    opacity: 0.3;
  }

  50% {
    opacity: 0.6;
  }

  100% {
    opacity: 0.3;
  }
}

// 添加响应式设计
@media (max-width: 768px) {
  .login-body {
    width: 90%;
    max-width: 400px;
    padding: 25px 20px;
  }

  .qrcode-box {
    width: 180px;
    height: 180px;
  }

  .form-title {
    font-size: 24px;

    &::before {
      left: -30px;
      font-size: 20px;
    }
  }

  .form-subtitle {
    font-size: 14px;
  }

  .form-item {
    ::v-deep .el-input__inner {
      height: 44px;
      font-size: 14px;
    }
  }

  .code-input-group {
    flex-direction: row;
    align-items: center;

    .code-input {
      flex: 1;
    }

    .verify-code-btn {
      height: 44px;
      min-width: 110px;
      font-size: 13px;
      white-space: nowrap;
    }
  }

  .third-party-login {
    flex-wrap: wrap;
    justify-content: space-around;
    gap: 15px;

    .login-icon {
      width: 40px;
      height: 40px;
      font-size: 20px;
    }
  }

  .switch-form-btn,
  .back-btn {
    width: 36px;
    height: 36px;
    top: 12px;
  }

  .back-btn {
    right: 56px;
  }
}

@media (max-width: 480px) {
  .login-body {
    width: 95%;
    padding: 20px 15px;
  }

  .code-input-group {
    .verify-code-btn {
      min-width: 95px;
      padding: 0 5px;
    }
  }
}

.code-text {
  color: #6366f1;
  font-weight: 500;

  i {
    cursor: pointer;
    margin-left: $spacing-sm;
  }
}

.form-header {
  text-align: center;
  margin-bottom: 36px;
  position: relative;

  &::after {
    content: '';
    position: absolute;
    bottom: -10px;
    left: 50%;
    transform: translateX(-50%);
    width: 60px;
    height: 3px;
    background: linear-gradient(90deg, #409EFF, #67C23A);
    border-radius: 3px;
  }
}

.form-title {
  font-size: 28px;
  font-weight: 700;
  margin: 0 0 10px;
  background: linear-gradient(120deg, #2b5dff 0%, #409eff 50%, #2b5dff 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  letter-spacing: 1px;
  position: relative;
  display: inline-block;

  &::before {
    position: absolute;
    left: -36px;
    top: 0;
    font-size: 24px;
    -webkit-text-fill-color: initial;
  }
}

/* 为每个表单添加不同的emoji */
.login-title::before {
  content: '👋';
}

.register-title::before {
  content: '🎉';
}

.forgot-title::before {
  content: '🔑';
}

.form-subtitle {
  font-size: 15px;
  color: #666;
  margin: 10px 0 0;
  opacity: 0.8;
}

.form-options {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding: 0 4px;

  :deep(.el-checkbox__label) {
    font-size: 14px;
    color: #606266;
  }

  :deep(.el-checkbox__input.is-checked)+.el-checkbox__label {
    color: #409eff;
  }
}

.forgot-link {
  color: $primary;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s;
  text-decoration: none;

  &:hover {
    color: darken($primary, 10%);
    text-decoration: underline;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.switch-form-btn,
.back-btn {
  position: absolute;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s;
  background: rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: rgba(64, 158, 255, 0.9);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  z-index: 10;
}

.switch-form-btn {
  top: 16px;
  right: 16px;

  &:hover {
    background: #409eff;
    color: white;
    transform: rotate(180deg);
  }

  i {
    font-size: 18px;
  }
}

.back-btn {
  top: 16px;
  right: 64px;

  &:hover {
    background: #409eff;
    color: white;
    transform: translateX(-4px);
  }

  i {
    font-size: 18px;
  }
}

.code-btn-item {
  display: flex;
  justify-content: flex-end;
  margin-top: -10px;
  margin-bottom: 25px;
}

.verify-code-btn {
  width: auto;
  min-width: 120px;
  height: 40px;
  background: linear-gradient(135deg, #409eff, #2b85e4);
  color: #fff;
  border: none;
  border-radius: 10px;
  font-size: 14px;
  transition: all 0.3s;
  box-shadow: 0 3px 8px rgba(64, 158, 255, 0.3);
  position: relative;
  overflow: hidden;

  i {
    margin-right: 5px;
  }

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 12px rgba(64, 158, 255, 0.4);
    background: linear-gradient(135deg, #4aa8ff, #3892ef);
  }

  &:active {
    transform: translateY(0);
    box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
  }

  &:disabled {
    background: linear-gradient(135deg, #a0d0ff, #83b7e7);
    cursor: not-allowed;
    transform: none;
  }

  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: all 0.6s;
  }

  &:hover:not(:disabled)::before {
    left: 100%;
  }
}

// 添加验证码输入框和按钮样式
.code-input-group {
  display: flex;
  margin-bottom: 20px;
  gap: 10px;

  .code-input {
    flex: 1;
    margin-bottom: 0;
  }

  .verify-code-btn {
    height: 48px;
    min-width: 130px;
    border-radius: 12px;
    background: linear-gradient(135deg, #409eff, #2b85e4);
    color: #fff;
    border: none;
    font-size: 14px;
    transition: all 0.3s;
    box-shadow: 0 3px 8px rgba(64, 158, 255, 0.3);
    position: relative;
    overflow: hidden;

    i {
      margin-right: 5px;
    }

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 5px 12px rgba(64, 158, 255, 0.4);
      background: linear-gradient(135deg, #4aa8ff, #3892ef);
    }

    &:active {
      transform: translateY(0);
      box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
    }

    &:disabled {
      background: linear-gradient(135deg, #a0d0ff, #83b7e7);
      cursor: not-allowed;
      transform: none;
    }

    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
      transition: all 0.6s;
    }

    &:hover:not(:disabled)::before {
      left: 100%;
    }
  }
}

/* 深色模式下验证码按钮样式 */
.dark-theme {
  .code-input-group {
    .verify-code-btn {
      background: linear-gradient(135deg, #3e8ee0, #246bb3);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);

      &:hover {
        background: linear-gradient(135deg, #409eff, #2b85e4);
        box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
      }

      &:disabled {
        background: linear-gradient(135deg, #355c8a, #254667);
        opacity: 0.6;
      }
    }
  }
}

/* 为验证码按钮添加更好的视觉效果 */
.code-input-group {
  display: flex;
  margin-bottom: 20px;
  gap: 10px;

  .code-input {
    flex: 1;
    margin-bottom: 0;
  }

  .verify-code-btn {
    height: 48px;
    min-width: 130px;
    border-radius: 12px;
    background: linear-gradient(135deg, #409eff, #2b85e4);
    color: #fff;
    border: none;
    font-size: 14px;
    font-weight: 600;
    transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
    box-shadow: 0 3px 8px rgba(64, 158, 255, 0.3), 0 1px 3px rgba(64, 158, 255, 0.2);
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;

    i {
      margin-right: 5px;
      transition: transform 0.3s;
    }

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 5px 12px rgba(64, 158, 255, 0.4), 0 2px 6px rgba(64, 158, 255, 0.2);

      i {
        transform: rotate(15deg);
      }
    }

    &:active {
      transform: translateY(1px);
      box-shadow: 0 2px 5px rgba(64, 158, 255, 0.3);
    }

    &:disabled {
      background: linear-gradient(135deg, #a0d0ff, #83b7e7);
      cursor: not-allowed;
      transform: none;
      opacity: 0.8;
    }

    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
      transition: all 0.6s;
    }

    &:hover:not(:disabled)::before {
      left: 100%;
    }
  }
}

/* 深色模式下验证码按钮样式 */
.dark-theme {
  .code-input-group {
    .verify-code-btn {
      background: linear-gradient(135deg, #3e8ee0, #246bb3);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.2);

      &:hover {
        background: linear-gradient(135deg, #409eff, #2b85e4);
        box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(0, 0, 0, 0.25);
      }

      &:disabled {
        background: linear-gradient(135deg, #355c8a, #254667);
        opacity: 0.7;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
      }

      /* 深色模式下添加文字阴影以增强可读性 */
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);

      /* 添加颜色变化动画 */
      &:not(:disabled)::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
        transition: opacity 0.3s;
        opacity: 0;
      }

      &:hover:not(:disabled)::after {
        opacity: 1;
        animation: pulse-btn 2s infinite;
      }
    }
  }
}

/* 添加按钮脉动动画 */
@keyframes pulse-btn {
  0% {
    opacity: 0.3;
  }

  50% {
    opacity: 0.6;
  }

  100% {
    opacity: 0.3;
  }
}

/* 验证对话框样式 */
:deep(.auth-dialog) {
  border-radius: 12px;
  overflow: hidden;

  .el-dialog__header {
    padding: 16px 20px;
    border-bottom: 1px solid #ebeef5;
    background: #f8f9fa;

    .el-dialog__title {
      font-weight: 600;
      font-size: 18px;
      color: #303133;
    }
  }

  .el-dialog__body {
    padding: 24px;
  }

  .el-dialog__footer {
    padding: 16px 20px;
    border-top: 1px solid #ebeef5;
  }
}

.auth-dialog-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 12px 0;

  .auth-icon {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background-color: #ecf5ff;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 16px;

    i {
      font-size: 32px;
      color: #409eff;
    }

    &.device-icon {
      background-color: #f0f9eb;

      i {
        color: #67c23a;
      }
    }
  }

  .auth-title {
    font-size: 18px;
    font-weight: 600;
    margin: 0 0 12px;
    color: #303133;
  }

  .auth-description {
    font-size: 14px;
    color: #606266;
    margin: 0 0 12px;
    line-height: 1.6;
    max-width: 90%;
  }

  .auth-tip {
    font-size: 13px;
    color: #909399;
    margin: 0 0 24px;
    padding: 8px 12px;
    background-color: #f0f9eb;
    border-radius: 4px;
    width: 90%;
    display: flex;
    align-items: flex-start;
    line-height: 1.5;

    i {
      margin-right: 6px;
      margin-top: 2px;
      color: #67c23a;
    }
  }
}

/* 暗色模式适配 */
@media (prefers-color-scheme: dark) {
  :deep(.auth-dialog) {
    .el-dialog__header {
      background: #1a1a1a;
      border-bottom-color: #333;
    }

    .el-dialog__footer {
      border-top-color: #333;
    }
  }

  .auth-dialog-content {
    .auth-icon {
      background-color: rgba(64, 158, 255, 0.15);

      &.device-icon {
        background-color: rgba(103, 194, 58, 0.15);
      }
    }

    .auth-title {
      color: #e0e0e0;
    }

    .auth-description {
      color: #a0a0a0;
    }
  }
}
</style>
